I know that sh just calls the default shell, so "bash -" means the same. But can someone explain the syntax to me. I tried looking in the bash manual, but couldn't find it. I came across this because I wanted to execute the output of a command. Ex.

echo date | sh -

prints out the date.


Yes, sh - and bash - do mean the same.

In man bash, there is this description (emphasis mine):

A -- signals the end of options and disables further option processing. Any arguments after the -- are treated as filenames and arguments. An argument of - is equivalent to --

That simply means that it signals the end of options and that any following tokens are arguments (not options) even if they start with a dash -.

And a POSIX sh has a similar description.

Thus, this volume of POSIX.1-2017 allows the single to mark the end of the options, in addition to the use of the regular "--" argument, because it was considered that the older practice was so pervasive.

This command:

$ echo "date" | sh -
Mon Feb 12 00:00:00 UTC 2018

But also does this:

$ echo "date" | sh
Mon Feb 12 00:00:00 UTC 2018

And this

$ echo "date" | sh -s
Mon Feb 12 00:00:00 UTC 2018

This will make clear what is being executed:

$ echo "date" | sh -x 
+ date
Mon Feb 12 00:00:00 UTC 2018

But this will fail:

$ echo "date" | sh - -x
sh: 0: Can't open -x

That means that the date string is being read as a command from the standard input and that the dash (-) signals the end of options and start the arguments (the same as -- would do).

  • Date | sh - wouldn’t work. echo date | sh - would though. Ok, so now we know what - does. It’s actually unnecessary. Can you do the same with xargs. I’m on a mac, so it’s BSD version of xargs. I tried echo date | xargs, but it didn’t work. – user242114 Feb 12 '18 at 3:55
  • Even on the Mac, echo date|xargs should print the word date to stdout. Of course in this case, you could simply write echo date, but redundantly piping it to xargs still should not cause any problem. What error message do you get? – user1934428 Feb 12 '18 at 7:28
  • I was trying to execute date. I could write “ echo date | xargs xargs, but that doesn’t work in the mac version of xargs. So eval doesn’t accept piped input, source has a bug in bash 3.2 (mac version) and you can’t do xargs xargs on the mac. This leaves us with using a while loop “while read line; do $line; done” – user242114 Feb 12 '18 at 13:56
  • The dash/hyphen is a standard option (or whatever it should be called) for POSIX sh (link). The way to force the shell to read from stdin is -s, e.g. echo 'echo "args: $*"' | bash -s - foo bar prints args: foo bar. – ilkkachu Aug 17 '18 at 8:54
  • 1
    @sofs1 It means that a (first only) - is equivalent to a (first only) --. Any further - or -- are treated as normal arguments not having special meaning. Well, actually, naming files for the shell. – Isaac Aug 10 '19 at 19:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.