Why my script returns a segmentation error when executing a command via ssh? - bash

I'm writing a bash script that is supposed to run applications with arguments on a remote computer. On the computer, root just needs to write the command:
# ./MyApp -t '{"name":"john"}'
So on my own computer I wrote a script (it is simplified in terms of what is actually to show the problem):
#!/bin/bash
VAR="{\"name\":\"john\"}"
echo "VAR: $VAR"
COMMAND="./MyAPP -t '$VAR'"
echo "COMMAND: $COMMAND"
ssh root#192.168.100.1 "$COMMAND"
Output:
$ ./my_script
VAR: {"name":"john"}
COMMAND: ./MyApp -t '{"name":"john"}'
root#192.168.100.1's password:
Segmentation fault
Why does I get segmentation error?

Related

Why is executing "docker exec" killing my SSH session?

Let's say I have two servers, A and B. I also have a bash script that is executed on server A that looks like this:
build_test.sh
#!/bin/bash
ssh user#B <<'ENDSSH'
echo "doing test"
bash -ex test.sh
echo "completed test"
ENDSSH
test.sh
#!/bin/bash
docker exec -i my_container /bin/bash -c "echo hi!"
The problem is that completed test does not get printed to the terminal.
Here's the output of running build_test.sh:
$ ./build_test
doing test
+ docker exec -i my_container /bin/bash -c "echo hi!"
hi!
I'm expecting completed test to be output after hi!, but it isn't. How do I fix this?
docker is consuming, though not using, its standard input, which it inherits from test.sh. test.sh inherits its standard input from bash, which inherits its standard input from ssh. This means that docker itself is reading the last line of the script before the remote shell can.
To fix, just redirect docker's standard input from /dev/null.
docker exec -i my_container /bin/bash -c "echo hi!" < /dev/null

Run shell script as sudo user along with its internal content on unix rhel

I have below script named as sample.sh
#!/bin/bash
echo "inside script file"
echo whoami
echo cftping -v
echo "Ping completed"
I am running it as other user with the help of below command.
sudo -H -u xfbcft bash -c 'bash /data/_temp/sample.sh'
I am getting below output:
xfbcft
/data/_temp/sample.sh: line 4: cftping: command not found
Ping completed
When I sudo to xfbcft directly then I can run 'cftping -v' command but not via above shell script. Could anyone guide me here?

Automate SSH and running commands

I am trying to automate SSH into a machine and then run some commands. However, I am getting stuck at the SSH portion:
for h in ${hosts[*]}; do
ssh -i foo.pem bc2-user#$h
echo "here"
sudo bash
cd /data/kafka/tmp/kafka-logs/
exit
exit
done
As soon as I run this script, I am able to SSH in but the automation stops at this message:
********************************************************************************
This is a private computer system containing information that is proprietary
and confidential to the owner of the system. Only individuals or entities
authorized by the owner of the system are allowed to access or use the system.
Any unauthorized access or use of the system or information is strictly
prohibited.
All violators will be prosecuted to the fullest extent permitted by law.
********************************************************************************
Last login: Thu Dec 10 10:19:23 2015 from 10.81.120.55
-bash: ulimit: open files: cannot modify limit: Operation not permitted
When I press control + d, my echo "here" commands executes and then my script exits. Without performing the rest of the commands.
I read around and I tried this but I am getting this syntax error:
./kafka_prefill_count.sh: line 38: warning: here-document at line 26 delimited by end-of-file (wanted `EOF')
./kafka_prefill_count.sh: line 39: syntax error: unexpected end of file
script:
for h in ${hosts[*]}; do
ssh -i foo.pem bc2-user#$h << EOF
echo "here"
sudo bash
cd /data/kafka/tmp/kafka-logs/
ls | grep "$dir_name"
exit
exit
bash -l
EOF
done
Your current script isn't really how you would execute commands remotely using ssh.
It should look more like this
shh -i foo.pem user#host 'echo "here" ; hostname'
(hostname command is just example to prove its running on other machine.
Good resource
Just saw your edit:
EOF needs to be all the way to the left.
ssh -i foo.pem bc2-user#$h << EOF
echo "here"
sudo bash
cd /data/kafka/tmp/kafka-logs/
ls | grep "$dir_name"
exit
exit
bash -l
EOF
Try this with two here documents, one for ssh and one for bash:
ssh -i foo.pem bc2-user#$h << EOF1
echo "remote"
sudo bash << EOF2
cd /data/kafka/tmp/kafka-logs/
ls | grep "$dir_name"
EOF2
EOF1

Function runs on CLI but not from bash script

I made a bash script to generate an ssh that I use all the time with a couple options. At the end it echos a string for whatever it is going to execute, and then it executes it. Currently I'm trying to add the functionality to add in a bash command to run once the ssh is completed, but its giving an error like so:
bash: /bin/echo 'hello'; bash -l: No such file or directory
Yet if I copy the command it runs, and run it from outside the executable, it runs perfectly. Is there any reason I would be getting this error from inside the executable, and not from the CLI?
An example command it generates is:
pair -c "/bin/echo 'hello'"
Running: ssh ****##.#.#.# -p443 -t "/bin/echo 'hello'; bash -l"
This is most likely caused because of too strong quoting. This error line
bash: /bin/echo 'hello'; bash -l: No such file or directory
shows that bash does not try to execute the command /bin/echo with the argument 'hello' followed by the command bash -l. Instead bash is trying to execute the command /bin/echo 'hello'; bash -l.
Compare:
$ ssh localhost -t "/bin/echo 'foo'; bash -l"
foo
$ logout # this is the new shell
Connection to localhost closed.
and:
$ ssh localhost -t '"/bin/echo 'foo'; bash -l"'
bash: /bin/echo foo; bash -l: No such file or directory
Connection to localhost closed.
The solution to this problem usually involves eval, but I cannot tell for sure unless I see more code from you.

using ssh with stat command bash [duplicate]

I'd like to execute several commands in sequence on a remote machine, and some of the later commands depend on earlier ones. In the simplest possible example I get this:
ssh my_server "echo this is my_server; abc=2;"
this is my_server
abc=2: Command not found.
ssh my_server "echo this is my_server; abc=2; echo abc is $abc"
abc: undefined variable
For a bit of background info, what I actually want to do is piece together a path and launch a java application:
ssh my_server 'nohup sh -c "( ( echo this is my_server; jabref_exe=`which jabref`; jabref_dir=`dirname $jabref_exe`; java -jar $jabref_dir/../jabref.jar` $1 &/dev/null ) & )"' &
jabref_dir: Undefined variable.
That way, whenever jabref gets updated to a new version on the server, I won't have to manually update the path to the jar file. The jabref executable doesn't take arguments, but launching it with java -jar does, which is why I have to juggle the path a bit.
At the moment I have the list of commands in a separate script file and call
ssh my_server 'nohup sh -c "( ( my_script.sh &/dev/null ) & )"' &
which works, but since the ssh call is already inside one script file it would be nice to have everything together.
In this example
ssh my_server "echo this is my_server; abc=2;"
abc is set on the remote side, so it should be clear why it is not set on your local machine.
In the next example,
ssh my_server "echo this is my_server; abc=2; echo abc is $abc"
your local shell tries to expand $abc in the argument before it is ever sent to the remote host. A slight modification would work as you expected:
ssh my_server 'echo this is my_server; abc=2; echo abc is $abc'
The single quotes prevent your local shell from trying to expand $abc, and so the literal text makes it to the remote host.
To finally address your real question, try this:
jabref_dir=$( ssh my_server 'jabref_exe=$(which jabref); jabref_dir=$(dirname $jabref_exe);
java -jar $jabref_dir/../jabref.jar > /dev/null; echo $jabref_dir' )
This will run the quoted string as a command on your remote server, and output exactly one string: $jabref_dir. That string is captured and stored in a variable on your local host.
With some inspiration from chepner, I now have a solution that works, but only when called from a bash shell or bash script. It doesn't work from tcsh.
ssh my_server "bash -c 'echo this is \$HOSTNAME; abc=2; echo abc is \$abc;'"
Based on this, the code below is a local script which runs jabref on a remote server (although with X-forwarding by default and passwordless authentication the user can't tell it's remote):
#!/bin/bash
if [ -f "$1" ]
then
fname_start=$(echo ${1:0:4})
if [ "$fname_start" = "/tmp" ]
then
scp $1 my_server:$1
ssh my_server "bash -c 'source load_module jdk; source load_module jabref; java_exe=\$(which java); jabref_exe=\$(which jabref); jabref_dir=\$(echo \${jabref_exe%/bin/jabref});eval \$(java -jar \$jabref_dir/jabref.jar $1)'" &
else
echo input argument must be a file in /tmp.
else
echo this function requires 1 argument
fi
and this is the 1-line script load_module, since modulecmd sets environment variables and I couldn't figure out how to do that without sourcing a script.
eval `/path/to/modulecmd bash load $1`;
I also looked at heredocs, inspired by How to use SSH to run a shell script on a remote machine? and http://tldp.org/LDP/abs/html/here-docs.html. The nice part is that it works even from tcsh. I got this working from the command line, but not inside a script. That's probably easy enough to fix, but I've got a solution now so I'm happy :-)
ssh my_server 'bash -s' << EOF
echo this is \$HOSTNAME; abc=2; echo abc is \$abc;
EOF

Resources