8

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.

9

1 Answer 1

6

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).

13
  • 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, 2018 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? Feb 12, 2018 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, 2018 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, 2018 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.
    – user232326
    Aug 10, 2019 at 19:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .