Your quoting is off.
"for dir in *; do
test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
done"
You have decided to delimit your string with double quotes "
, but they are included in your string.
Either escape the other quotes:
"for dir in *; do
test -d \"\$dir\" && ( find \"\$dir\" -name '*test' | grep -q . || echo \"\$dir\" );
done"
(error prone, ugly)
… or use another delimiter: Perl offers you a wide range of possibilities. These quoting syntaxes interpolate variables inside: "…"
and qq{…}
where you can use any character in [^\s\w]
as delimiter, and non-interpolating syntaxes are: '…'
and q{…}
with the same delimiter flexibility as before:
qq{for dir in *; do
test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
done}
The q
and qq
constructs can include the delimiter inside the string, if the occurrence is balanced: q( a ( b ) c )
works.
The third quoting mechanism is a here-doc:
system( <<END_OF_BASH_SCRIPT );
for dir in *; do
test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
done
END_OF_BASH_SCRIPT
This is usefull for including longer fragments without worrying about a delimitor. The String is ended by a predefined token that has to appear on a line of its own. If the delimitor declaration is placed in single quotes (<<'END_OF_SCRIPT'
), no variables will be interpolated:
system( <<'END_OF_BASH_SCRIPT' );
for dir in *; do
test -d "$dir" && ( find "$dir" -name '*test' | grep -q . || echo "$dir" );
done
END_OF_BASH_SCRIPT
Note on the q{}
and qq{}
syntax: This is a feature never to be used outside of obfuscation, but it is possible to use a character in \w
as the delimiter. You have to include a space between the quoting operator q
or qq
and the delimiter. This works: q xabcx
and is equal to 'abc'
.