4 ms·
I've solved this problem with the following 2 POSIX functions. https://mullikine.github.io/posts/missing-posix-shell-functions-cmd-and-myeval/ https://mullikin
by mullikine 5y ago
I've solved this problem with the following 2 POSIX functions.
https://mullikine.github.io/posts/missing-posix-shell-functions-cmd-and-myeval/ https://mullikine.github.io/posts/missing-posix-shell-functi...
cmd() { for var in "$@"; do printf "'%s' " "$(printf %s "$var" | sed "s/'/'\\\\''/g")"; done | sed 's/ $//'; }
myeval() { eval "$(cmd "$@")"; }
`cmd` is by far the most useful of the two. It returns the arguments it was given, properly escaped. You can use it to capture the arguments as a string and then pass them to ssh.
# The following captures the arguments to the running script as a string.
CMD="$(cmd "$@")"
# Another example, could be putting some command into a string.
CMD="$(cmd echo "This will run on the server")"
# Then you run ssh as follows.
ssh remotehost "$CMD"
# Or something like this.
ssh remotehost "$(cmd echo "This will run on the server")"
The real power is in nesting!
ssh remotehost "$(cmd echo "This will run on the server" "$(cmd "Now I don't need" "to worry" "$(cmd About "escaping escapes")")")"
That will generate these escapes.
'ssh' 'remotehost' ''\''echo'\'' '\''This will run on the server'\'' '\'''\''\'\'''\''Now I don'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''t need'\''\'\'''\'' '\''\'\'''\''to worry'\''\'\'''\'' '\''\'\'''\'''\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''About'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'' '\''\'\'''\''\'\''\'\'''\'''\''\'\'''\''escaping escapes'\''\'\'''\''\'\''\'\'''\'''\''\'\'''\'''\''\'\'''\'''\'''
- ptx 5y agoWhy is this downvoted? What's the problem with this solution? It looks like the same kind of thing as Python's shlex.quote, which should work and about which the manual[1] says: "The returned value is a string that can safely be used as one token in a shell command line, for cases where you cannot use a list." [1] https://docs.python.org/3/library/shlex.html#shlex.quote https://docs.python.org/3/library/shlex.html#shlex.quote
- mullikine 5y agoI made too many edits. HN autovoted down. It's legit
- Aachen 5y agoI don't think editing your post results in the server downvoting it. Not sure if I understood your comment correctly.
- mullikine 5y ago`myeval` is more subtle. It is like eval but reliably escapes and evaluates the arguments as a single command. cmd 'hello '\'''\'''\'''\''"simon' 'thanks' 'for' 'lunch' # Output: 'hello '\'''\'''\'''\''"simon' 'thanks' 'for' 'lunch' # The fact that myeval seems useless here is testament to its greatness myeval cmd 'hello '\'''\'''\'''\''"simon' 'thanks' 'for' 'lunch' # Output: 'hello '\'''\'''\'''\''"simon' 'thanks' 'for' 'lunch' # eval isn't great though eval cmd 'hello '\'''\'''\'''\''"simon' 'thanks' 'for' 'lunch' # Error: zsh: unmatched "