ssh: bash: line 5: syntax error near unexpected token `(' [duplicate] - bash

for example:
ssh localhost echo *([^.])
requires me to pass -O extglob to the remote shell bash like so:
ssh localhost -O extglob echo *([^.])
however, ssh then thinks the -O is for itself, so I try again:
ssh localhost -- -O extglob echo *([^.])
but then bash thinks -- is for itself.
how can I pass -O extglob to bash through ssh?
thanks.
update: i would prefer not to ask ssh to ask bash to launch another bash:
ssh yourserver bash -O extglob -c "'echo *([^.])'"

Update: As mentioned in the comments the extglob will lead to a syntax error. I've managed it by piping the command to stdin:
ssh yourserver -- bash -O extglob <<'EOF'
echo *([^.])
EOF
I would start an additonal shell remotely. Like this:
ssh yourserver bash -O extglob -c 'ls -al'
Although it is not required in this example I would advice you to use -- after ssh arguments (as you mentioned):
ssh yourserver -- bash -O extglob -c 'ls -al'
This will prevent ssh from parsing the command to execute remotely as arguments.
But you can also pass the option to the shell ssh itself starts for you using the shopt bash builtin. Note that ; separates the two commands.
ssh yourserver -- 'shopt -s extglob; ls -al'

Related

Bash Script: How to run command with $myVar as one of the arguments?

I have a bash script that SSHes into 2 machines and runs identical commands.
I'd like to store this in a var, but I'm not sure how to reference the contents of the var when running the command
ssh -o StrictHostKeyChecking=no ubuntu#123.123.123 -i ./travis/id_rsa <<-END
sudo su;
...
echo "Done!";
END
ssh -o StrictHostKeyChecking=no ubuntu#456.456.456 -i ./travis/id_rsa <<-END
sudo su;
...
echo "Done!";
END
I tried something like this but it didn't work:
script=$(cat <<-END
sudo su;
...
echo "Done!";
END
)
ssh -o StrictHostKeyChecking=no ubuntu#123.123.123 -i ./travis/id_rsa $script
ssh -o StrictHostKeyChecking=no ubuntu#456.456.456 -i ./travis/id_rsa $script
If I am at all able to understand what you are asking, you really don't want to put the commands in a variable.
for host in 123.123.123 456.456.456; do
ssh -o StrictHostKeyChecking=no ubuntu#"$host" -i ./travis/id_rsa<<-\____here
sudo -s <<-_________there
: your script goes here
________there
echo "Done."
____here
done
If you really wanted to assign a multi-line variable (but trust me, you don't) the syntax for that is simply
script='sudo -s <<\____there
: your commands
____there
echo "Done."'
But there really is no need to do this, andeit actually complicates things down the line. You see, passing in properly quoted strings as arguments to ssh is extremely tricky - you have the local shell and the remote shell and both require additional quoting or escaping in order to correctly pass through shell metacharacters; and the usual caveats with eval apply, only you are effectively running a hidden eval by way of passing in executable code as a string for the remote shell.
I believe you want to do something like this:
cmds="sudo bash -c 'command1; command2; command3;'"
ssh ... "$cmds"

Use Bash with script text from stdin and options from command line

I want to use /bin/bash (possibly /bin/sh) with the option -f passed to, and handled by, the script.
Precisely,
while getopts f OPT
do
case $OPT in
"f" ) readonly FLG_F="TRUE"
esac
done
if [ $FLG_F ]; then
rm -rf $KIBRARY_DIR
fi
and when these lines are in a file http://hoge.com/hoge.sh,
I can do this, for instance,
wget http://hoge.com/hoge.sh
/bin/bash hoge.sh -f
but not
/bin/bash -f hoge.sh
I know the reason but I want to do like this,
wget -O - http://hoge.com/hoge.sh | /bin/bash
with -f option for hoge.sh not for /bin/bash
Are there any good ways to do this?
/bin/bash <(wget -O - http://hoge.com/hoge.sh) -f
worked. but this is only for bash users, right?
Using bash you can do
wget -O - http://hoge.com/hoge.sh | /bin/bash -s -- -f
as with -s commands are read from the standard input. This option allows the positional parameters to be set too.
It should work with other POSIX shells too.

running a pipe command with variable substitution on remote host

I'd to run a piped command with variable substitution on a remote host and redirect the output. Given that the login shell is csh, I have to used "bash -c". With help from users nlrc and jerdiggity, a command with no variable substitution can be formulated as:
localhost$ ssh -f -q remotehost 'bash -c "ls /var/tmp/ora_flist.sh|xargs -L1 cat >/var/tmp/1"'
but the single quote above will preclue using variable substitution, say, substituting ora_flist.sh for $filename. how can I accomplish that?
Thanks.
Something like this should work:
ssh -f -q remotehost 'bash -c "ls /var/tmp/ora_flist.sh|xargs -L1 cat >/var/tmp/1"'
So your problem was that you want the shell variable to be extended locally. Just leave it outside the single quotes, e.g.
ssh -f -q remotehost 'bash -c "ls '$filename' | xargs ..."'
Also very useful trick to avoid the quoting hell is to use heredoc, e.g.
ssh -f -q remotehost <<EOF
bash -c "ls $filename | xargs ... "
EOF

pass arguments to remote shell in ssh

for example:
ssh localhost echo *([^.])
requires me to pass -O extglob to the remote shell bash like so:
ssh localhost -O extglob echo *([^.])
however, ssh then thinks the -O is for itself, so I try again:
ssh localhost -- -O extglob echo *([^.])
but then bash thinks -- is for itself.
how can I pass -O extglob to bash through ssh?
thanks.
update: i would prefer not to ask ssh to ask bash to launch another bash:
ssh yourserver bash -O extglob -c "'echo *([^.])'"
Update: As mentioned in the comments the extglob will lead to a syntax error. I've managed it by piping the command to stdin:
ssh yourserver -- bash -O extglob <<'EOF'
echo *([^.])
EOF
I would start an additonal shell remotely. Like this:
ssh yourserver bash -O extglob -c 'ls -al'
Although it is not required in this example I would advice you to use -- after ssh arguments (as you mentioned):
ssh yourserver -- bash -O extglob -c 'ls -al'
This will prevent ssh from parsing the command to execute remotely as arguments.
But you can also pass the option to the shell ssh itself starts for you using the shopt bash builtin. Note that ; separates the two commands.
ssh yourserver -- 'shopt -s extglob; ls -al'

Using bash -c and Globbing

I'm running gnu-parallel on a command that works fine when run from a bash shell but returns an error when parallel executes it with bash using the -c flag. I assume this has to do with the special globbing expression I'm using.
ls !(*site*).mol2
This returns successfully.
With the flag enabled the command fails
/bin/bash -c 'ls !(*site*).mol2'
/bin/bash: -c: line 0: syntax error near unexpected token `('
The manual only specifies that -c calls for bash to read the arguments for a string, am I missing something?
Edit:
I should add I need this to run from a gnu-parallel string, so the end resultant command must be runnable by /bin/bash -c "Some Command"
You should try the following code :
bash <<EOF
shopt -s extglob
ls !(*site*).mol2
EOF
Explanation :
when you run bash -c, you create a subshell, and shopt settings are not inherited.
EDIT
If you really need a one liner :
bash -O extglob -c 'ls !(*site*).mol2'
See this thread

Resources