6

I am writing a bash script that takes a number of command line arguments (possibly including spaces) and passes all of them to a program (/bin/some_program) via a login shell. The login shell that is called from the bash script will depend on the user's login shell. Let's suppose the user uses /bin/bash as their login shell in this example... but it might be /bin/tcsh or anything else.

If I know how many arguments will be passed to some_program, I can put the following lines in my bash script:

#!/bin/bash
# ... (some lines where we determine that the user's login shell is bash) ...
/bin/bash --login -c "/bin/some_program \"$1\" \"$2\""

and then call the above script as follows:

my_script "this is too" cool

With the above example I can confirm that some_program receives two arguments, "this is too" and "cool".

My question is... what if I don't know how many arguments will be passed? I'd like to pass all the arguments that were sent to my_script along to some_program. The problem is I can't figure out how to do this. Here are some things that don't work:

/bin/bash --login -c "/bin/some_program $@"     # --> 3 arguments: "this","is","too"
/bin/bash --login -c /bin/some_program "$@"     # --> passes no arguments
JCOidl
  • 452
  • 1
  • 5
  • 12

2 Answers2

9

Quoting the bash manual for -c:

If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.

Works for me:

$ cat x.sh
#!/bin/bash
/bin/bash --login -c 'echo 1:$1 2:$2 3:$3' echo "$@"
$ ./x.sh "foo bar" "baz" "argh blargh quargh"
1:foo bar 2:baz 3:argh blargh quargh

I don't know how you arrived at the "passes no arguments" conclusion, maybe you missed the $0 bit?

themel
  • 8,825
  • 2
  • 32
  • 31
3

Avoid embedding variables into other scripts, pass them on as arguments instead. In this case:

bash --login -c 'some_program "$@"' some_program "$@"

The first argument after -c '...' is taken as $0, so I just put in some_program there.

On a side note, it's an odd requirement to require a login shell. Doesn't the user log in?

geirha
  • 5,801
  • 1
  • 30
  • 35
  • I missed the $0 part, thanks! Much appreciate it. Now how would one format this if the path to some_program was also stored in a variable (say $cmd)? Also, you're correct about the login shell part... that's not actually necessary. – JCOidl Aug 21 '12 at 17:28
  • @JCOidl `bash -c '"$@"' _ "$cmd" "$@"` though if you don't need the login shell, then you don't need to invoke a new instance of bash either, just run it in the current script. `"$cmd" "$@"` – geirha Aug 21 '12 at 17:34
  • I don't understand the underscore notation here. The reason I am not simply using `"$cmd" "$@"` is that this script is being called from an OSX program which needs access to the user's environment. So in some cases I will have to call /bin/tcsh, /bin/ksh, etc. – JCOidl Aug 21 '12 at 18:04
  • @JCOidl I just used _ instead of some_command to shorten it. $0 isn't used anyway. However, the user's environment should be loaded when the user logs in, and inherited by all processes thereafter, so I don't see your point. – geirha Aug 21 '12 at 18:22
  • Yeah... it's confusing. OSX keeps the environmental variables available to GUI apps separate from those available to UNIX-type programs launched from the terminal. So logging in to the GUI doesn't automatically load the environment that is set in .profile or .cshrc or whatever corresponds to the user's default shell. At any rate, even substituting the program name (or `$cmd`) for the underscore results in a `command not found` error. _PS - Thanks for the back and forth here. It's been incredibly useful._ – JCOidl Aug 21 '12 at 18:38
  • @JCOidl Attempting to load an interactive login shell, for every shell known to man will likely be a lot of work, and mostly different from shell to shell. Wouldn't it be better to just educate the users on the right way to set environment variables? https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/EnvironmentVars.html – geirha Aug 21 '12 at 20:36