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

2 Answers 2

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?

Sign up to request clarification or add additional context in comments.

Comments

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?

6 Comments

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 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" "$@"
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 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.
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.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.