General tip: if you have two levels of nesting, avoid using single quotes in the inner command, and use single quotes around the outer command.
Additional tip: don't use backticks - `…`
- to execute code, instead use $(…)
around it. Dollar-parentheses is pretty much DWIM('Do what I mean') when it comes to nested quotes; backquotes have arcane, shell-dependent rules.
watch -n 3 'for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'
If you need single quotes inside a single-quoted command, you can use '\''
. Think of these four characters as the way to quote a single quote inside single quotes, though technically speaking this is constructed as end the single-quoted string, append a literal single quote, and start a new single-quoted string (still appended to the current word).
For more complex cases, either painstakingly count the quotes, or define temporary variables.
cmd='for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "rusage[mem=7000]" "$x"; done'
watch_cmd='watch -n 3 "$cmd"'
This answer isn't specific to zsh. Zsh doesn't bring anything major here. You can save a bit of quoting because there's no need for double quotes around command substitutions, and sometimes there are ways to use built-ins rather than external commands which reduce the quoting needs, but the underlying issues are the same as in other shells.
Oh, and by the way, note that watch
will execute your command in sh
, not in zsh. If you want to execute the command in zsh, you need to run
watch -n 3 -x zsh -c "$cmd"
on Debian/Ubuntu, and
export cmd
watch -n 3 'exec zsh -c "$cmd"'
(even more quoting!) elsewhere.
Let say $1 is
This is a test directory name
We escape the double quote because we want to pass the target directory (part after colon) as a whole (including the double quotes) to the target machine.
Following is what we want to past to target
/Volumes/Seagate3To/"This is a test directory name"
Without the escape, the double quote will be consumed by the local machine and following string is sent, which become 6 strings separated by space
/Volumes/Seagate3To/This is a test directory name
Resulting an error.
Best Answer
zsh: