The usual way would be to save a copy of arg1 ("$1"
) and shift the parameters by one, so you can refer to the whole list as "$@"
:
#!/bin/sh
arg1="$1"
shift 1
/path/to/a/program "$@"
bash has some array support of course, but it is not needed for the question as posed.
If even arg1 is optional, you would check for it like this:
if [ $# != 0 ]
then
arg1="$1"
shift 1
fi
While ssh
provides for two separate output streams (for stdout and stderr), it only feeds one input stream (stdin). So you'd need either to pass the script content and input file via different mechanisms.
For instance, one via a variable, one via stdin:
LC_CODE=$(cat local_script.sh) ssh host 'eval "$LC_CODE"' < input
(assuming both your ssh
client passes the LC_*
variable (SendEnv
in ssh_config
) and the sshd
server accepts them (AcceptEnv
in sshd_config
))
Or simply pass the content of the local_script.sh
as the remote shell code assuming the login shell of the remote user is the right one for the syntax of that script:
ssh host "$(cat local_script.sh)" < input
Or concatenate the code and input fed to ssh
's stdin like with:
{
echo '{'; cat local_script.sh; echo '}; exit'
cat input
} | ssh host 'bash -s some arguments'
Here using bash
because bash
will take care of reading the input one byte at a time so as not to read past that }; exit
line while not all other shells do that.
Or if sed
on the remote host is GNU sed
:
echo '#END-OF-SCRIPT' | cat local_script.sh - input |
ssh host 'set some arguments; eval "$(sed -u "/^#END-OF-SCRIPT/q")"'
(here having the code evaluated by the login shell of the remote user and assuming it's Bourne-like)
Best Answer
Another way to do this thing is to name the parameter you want to declare and then do so:
OUTPUT
In the above example the explicitly declared environment variable is preferred to the command-line argument, but the command-line argument is used when the environment variable is either empty or unset. When both the 8th positional and the environment variable
$eight
are empty or unset the default value some_default is assigned to$eight
. In either case the:
can be removed from the:-
or:=
statements if empty should be an acceptable value.The variable
$eight
could as well have been set like:... and the previous line omitted entirely but I wanted to demonstrate that declaring a variable in that way does result in a persistent value, and so I did it in two commands. Either way
$eight
is set to the final value of that compound parameter expansion.getopts
- for robust scripts - often is the best way to handle command options. Positional parameters, on the other hand, are almost always the most simple means of robustly handling operands in a script.For example:
OUTPUT
There we only see the eighth operand, but there are 101 of them globbed from my test directory.