15

I am trying to run a program like this:

$CMD $ARGS

where $ARGS is a set of arguments with spaces. However, zsh appears to be handing off the contents of $ARGS as a single argument to the executable. Here is a specific example:

$export ARGS="localhost -p22"
$ssh $ARGS
ssh: Could not resolve hostname localhost -p22: Name or service not known

Is there a bash or zsh flag that controls this behavior?

Note that when I put this type of command in a $!/bin/sh script, it performs as expected.

Thanks,

SetJmp

ZyX
  • 52,536
  • 7
  • 114
  • 135
Setjmp
  • 27,279
  • 27
  • 74
  • 92
  • Doesn't it mean zsh is not POSIX-compliant? – jpalecek Sep 08 '11 at 22:02
  • @jpalecek It is not unless explicitely requested (by setting some options, by calling it using `**/sh` -> `/bin/zsh` symlink or by using `emulate sh` (which in turn just sets some options)). – ZyX Sep 09 '11 at 19:49

3 Answers3

23

In zsh it's easy:

Use cmd ${=ARGS} to split $ARGS into separate arguments by word (split on whitespace).

Use cmd ${(f)ARGS} to split $ARGS into separate arguments by line (split on newlines but not spaces/tabs).

As others have mentioned, setting SH_WORD_SPLIT makes word splitting happen by default, but before you do that in zsh, cf. http://zsh.sourceforge.net/FAQ/zshfaq03.html for an explanation as to why whitespace splitting is not enabled by default.

Michael Bosworth
  • 2,123
  • 18
  • 8
7

If you want to have a string variable (there are also arrays) be split into words before passing to a command, use $=VAR. There is also an option (shwordsplit if I am not mistaking) that will make any command $VAR act like command $=VAR, but I suggest not to set it: I find it very inconvenient to type things like command "$VAR" (zsh: command $VAR) and command "${ARRAY[@]}" (zsh: command $ARRAY).

ZyX
  • 52,536
  • 7
  • 114
  • 135
5

It will work if you use eval $CMD $ARGS.

Tom Zych
  • 13,329
  • 9
  • 36
  • 53