Mark
Mark

Reputation: 2148

pass bash script args as named parameters to a command inside the script

I have a bash script that takes two parameters. Inside that script, I need to call ssh using a heredoc and call a method that expects the two arguments. For example:

ssh -o "IdentitiesOnly=yes" -t -i $key -l user localhost << 'ENDSSH'
/my_python_app.py -u -t tar -p $1 -f $2
ENDSSH

key is set by my script, I know that part is good.

However, my_python_app prints out args and it doesn't show any arguments for -p and -f

I would call my script like

my_script /tmp filename

I use argparse in my python app, but I am also printing out sys.argv and it gives me:

['my_python_app.py', '-u', '-t', 'tar', '-p', '-f']

Note there are no values received for -p and -f. (-u is a flag, and that is set correctly).

How do I pass $1 and $2 to my_python_app as the -p and -f values?

Upvotes: 0

Views: 1318

Answers (2)

Charles Duffy
Charles Duffy

Reputation: 295443

The more paranoid way to do this would be:

# store these in an array to reduce the incidental complexity below
ssh_args=( -o "IdentitiesOnly=yes" -t -i "$key" -l user )

posixQuote() {
  python -c 'import sys, pipes; sys.stdout.write(pipes.quote(sys.argv[1])+"\n")' "$@"
}

ssh "${ssh_args[@]}" localhost "bash -s $(posixQuote "$1") $(posixQuote "$2")" << 'ENDSSH'
/path/to/my_python_app.py -u -t tar -p "$1" -f "$2"
ENDSSH

If you know with certainty that the destination account's shell matches the local one (bash if the local shell is bash, ksh if the local shell is ksh), consider the following instead:

printf -v remoteCmd '%q ' /path/to/my_python_app.py -u -t tar -p "$1" -f "$2"
ssh "${ssh_args[@]}" localhost "$remoteCmd"

Upvotes: 1

Gordon Davisson
Gordon Davisson

Reputation: 125798

Remove the quotes around the here-document delimiter (i.e. use << ENDSSH instead of << 'ENDSSH'). The quotes tell the shell not to expand variable references (and some other things) in the here-document, so $1 and $2 are passed through to the remote shell... which doesn't have any parameters so it replaces them with nothing.

BTW, removing the single-quotes may not fully work, since if either argument contains whitespace or shell metacharacters, the remote end will parse those in a way you probably don't intend. As long as neither argument can contain a single-quote, you can use this:

ssh -o "IdentitiesOnly=yes" -t -i $key -l user localhost << ENDSSH
/my_python_app.py -u -t tar -p '$1' -f '$2'
ENDSSH

If either might contain single-quotes, it gets a little more complicated.

Upvotes: 3

Related Questions