No, that nesting of substitution operators is unique to zsh
.
Note that with zsh
like with (t)csh
, you can also do ${PWD:t:s/trunk/latest/}
.
Though bash
also supports those csh history modifiers for history expansion, it doesn't support them for its parameter expansions.
Here with bash
, use a temporary variable:
var=${PWD##*/} var=${var//trunk/latest}
Here (linebreaks added),
$ task add "first line doesn\'t say much
Second line says a lot but part of this line does not appear in the
resulting description 'truncate -s0 !(temp_file | temp_dir)' truncates
all files to 0 bytes as shown by: '`wc -l *`'"
the whole string is double-quoted, so command substitutions and other expansions will run there. That happens in the shell, before task
sees that string, and you'll need to prevent it with backslashes or putting that part in single quotes.
E.g.
$ printf "%s\n" "...shown by: '\`wc -l *\`'"
...shown by: '`wc -l *`'
So,
task add "...shown by: '\`wc -l *\`'"
would pass the string ...shown by: '`wc -l *`'
to task
. It's up to it what does with that.
If you don't want to use backslashes, here's the way to put it in single quotes:
# aaaaaaaaaaaaaaaaBBBBBBBBBBBaaa
$ printf "%s\n" "...shown by: '"'`wc -l *`'"'"
...shown by: '`wc -l *`'
(The a
's mark the double-quoted parts, the B
's the single-quoted parts. They are just concatenated on the shell command line. The literal single quotes are within the double-quoted strings.)
As for the single quote and the backslash, you don't need to escape a single quote within double quotes, and in fact the backslash will remain there:
$ printf "%s\n" "foo'bar"
foo'bar
$ printf "%s\n" "foo\'bar"
foo\'bar
From what you show, it seems like task
removes at least the first single-quoted string from the argument (plus a word after that, since the removed part was 't say much ... 'truncate
)
The shell will not do that, this works fine:
$ printf "%s\n" "a 'quoted string' to test"
a 'quoted string' to test
What's causing the shell to remove the part of the argument to task
between \
(backslash) and -s
,
It's highly likely it's not the shell doing that.
and how do you prevent the shell from interpreting the above single-quoted command substitution (i.e. '`wc -l *`'
)?
It's not single-quoted, it's double-quoted with quoted single quotes next to it.
Best Answer
You have mistaken, double quotes
"$b"
does not prevent parameter expansion, it prevents pathname expansion (aka globbing) and fields splitting.If you want to prevent parameter expansion, you need to use quoting, like single quote
'$b'
or escaping\$b
:or:
then
$b
is output literal.In the example, there's nothing prevent parameter expansion.
When the shell read the input
c=$(b=2; echo $b)
, it perform token recognition, saw that$(
is token for command substitution. So it treats the rest of string between$(
and)
to be interpreted in subshell created by command substitution, not the current shell.