Bash, Systemd Service, command substitution - Not playing well together - bash

I have the following in my redis#.service file:
...
ExecStop=/bin/bash -c \"/usr/local/bin/redis-cli -p $(echo %i | awk -F \'.\' \'{ print $2 }\') shutdown\"
...
Then when I run:
sudo systemctl stop redis#redis.6379.test-site.com.service
Followed by:
sudo systemctl status redis#redis.6379.test-site.com.service
I get:
...
Process: 10042 ExecStop=/bin/bash -c "/usr/local/bin/redis-cli -p $(echo redis.6379.test-site.com | awk -F '.' '{ print $2 }') shutdown" (code=exited, status=1/FAILURE)
...
Sep 10 17:36:53 hostname bash[10042]: -p: -c: line 0: unexpected EOF while looking for matching `"'
Sep 10 17:36:53 hostname bash[10042]: -p: -c: line 1: syntax error: unexpected end of file
Then if I run:
sudo systemctl start redis#redis.6379.test-site.com.service
Followed by (taken from the systemctl status output):
/bin/bash -c "/usr/local/bin/redis-cli -p $(echo redis.6379.test-site.com | awk -F '.' '{ print $2 }') shutdown"
Then the command works as expected...
Can anyone shed some light as to what's happening here?
If Systemd is just running the command shown for ExecStop, and that command works just fine when run manually, shouldn't it also work when systemd runs it?
I have a feeling it's something to do with the quoting, but I'm too much of a newb at bash to wrap my head around it.

Related

Injecting a script to Pod with docker returns EOF

my goal is to execute a script once on a permanently running pod in kubernetes. The pod is called busybox-<SOME_ID> and finds itself in the namespace default.Therefore, I wrote this script - called scan-one-pod.sh:
#!/bin/bash
export MASTER_IP=192.168.56.102
export SCRIPT_NAME=script.sh
export POD_NAMESPACE=default
export POD_NAME=busybox
echo "echo HALLO" | ssh ubuntu#$MASTER_IP
export POD_ID=$(kubectl get po | grep busybox | sed -n '1p'|awk '{print $1}')
kubectl cp $SCRIPT_NAME $POD_NAMESPACE/$POD_ID:.
kubectl exec $POD_ID -- chmod +x $SCRIPT_NAME
export CONTAINER_ID=$(kubectl describe pod busybox | grep 'Container ID' | sed -n '1p'|awk '{print $3}')
ssh -t ubuntu#$MASTER_IP "sudo docker exec -u root $CONTAINER_ID -- ./script.sh"
The referred script script.sh has the following content:
$ kubectl exec $POD_ID -- cat script.sh
#!/bin/bash
echo "test" >> test
cp test test-is-working
However, it is not possible to run the script on the pod:
the files test and test-is-working are not created
the script scan-one-pod.sh returns just EOF:
$ ./scan-one-pod.sh
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-87-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
155 Software-Pakete können aktualisiert werden.
72 Aktualisierungen sind Sicherheitsaktualisierungen.
HALLO
[sudo] Passwort für ubuntu:
EOF
Connection to 192.168.56.102 closed.
If I execute the docker-command directly, remote on my kubernetes-controller, I get the same message of EOF:
ubuntu#controller:~$ export CONTAINER_ID=$(kubectl describe pod busybox | grep 'Container ID' | sed -n '1p'|awk '{print $3}')
ubuntu#controller:~$ sudo docker exec -u root $CONTAINER_ID ./script.sh
EOF
If I execute it from my local workstation via kubectl exec I get this error:
$ kubectl exec $POD_ID ./script.sh
rpc error: code = 13 desc = invalid header field value "oci runtime error: exec failed: container_linux.go:247: starting container process caused \"no such file or directory\"\n"
I don't know, which missing file they are referring to, but the script.sh-file is present and the busybox-pod seems to be running:
$ kubectl exec $POD_ID ls script.sh
script.sh
$ kubectl get po busybox-6bdf9b5bbc-4skds
NAME READY STATUS RESTARTS AGE
busybox-6bdf9b5bbc-4skds 1/1 Running 10 12d
Question: As far as I know, EOF means End-Of-File. End of which file would be important for me to know, and why is that a problem?
Thanks in advance, any help is appreciated :)

Unable to run shell command with docker?

I have installed docker on Ubuntu 14.04. Now when i am trying to create one test job in docker, i am getting the below error:
$ sample_job=$(docker run -d busybox /bin/sh -c “while true; do echo
Docker; sleep 1; done”)
-bash: command substitution: line 228: syntax error near unexpected token `do'
-bash: command substitution: line 228: `docker run -d busybox /bin/sh -c “while true; do echo Docker; sleep 1; done”)'
I am following the below blog for starting with docker: http://blog.flux7.com/blogs/docker/docker-tutorial-series-part-2-the-15-commands
Could someone help me in resolving this issue.
Thanks!!
Credit goes to Cyrus:
Replaced “ by "
$ sample_job=$(docker run -d busybox /bin/sh -c "while true; do echo
Docker; sleep 1; done")

Killing Process on Remote Host using Fabric

I am writing a script using Fabric which needs to terminate a process remotely.
(this means that the command ends up getting executed as /bin/bash command)
The current code I have is the following:
in a kill.sh file i have
/bin/kill $(ps -ef | grep multiserver.jar | grep -v bin/sh | grep -v /bin/bash | grep -v sh | grep python | grep -v /usr/bin/java | grep -v /usr/bin/python | grep -v sh | awk '{print $2}')
which I run in Fabric on my remote host using the following commands
local("scp " + "kill.sh " + user +"#" + server_address + ":" + directory)
run ("chmod u+x kill.sh")
run("./kill.sh")
However I get the following error message
out: Usage:
[] out: kill [options] <pid> [...]
Fatal error: run() received nonzero return code 1 while executing!
Requested: ./kill.sh
Executed: /bin/bash -l -c "cd ... && ./kill.sh"
Does anyone know what I am doing wrong?
While solving this issue with reading logs with fabric, I wrote command to kill remote processes:
with settings(warn_only=True):
sudo("kill -9 `ps aux | <pipeline of greps> | awk '{print $2}'`")
Hope this helps.

bash script works on bootup, doesn't in terminal

I'm creating a server in Amazon ec2 and passing it a bash script as userdata, which is run when the server first boots. It includes a command to add a line to crontab for a user using the answer given here.
directory="/home/intahwebz/current/tools/amazon/"
command="cd $directory && sh backupSQLToS3.sh"
job="15 1 */2 * * $command"
cat <(fgrep -i -v "$command" <(crontab -u intahwebz -l)) <(echo "$job") | crontab -u intahwebz -
This script appears to work fine during bootup as it displays no error messages and the cronjob is installed in the crotab.
However I'd also like the script to run during server upgrades. Attempting to run the script from the command line gives the error:
installCrontab.sh: line 14: syntax error near unexpected token `('
installCrontab.sh: line 14: `cat <(fgrep -i -v "$command" <(crontab -u intahwebz -l)) <(echo "$job") | crontab -u intahwebz -'
What do I need to fix this error?
your approach is working perfectly for me:
$ whoami
test
$ echo $SHELL
/bin/bash
$ command="cd $directory && sh backupSQLToS3.sh"
$ job="15 1 */2 * * $command"
$ crontab -l
$ cat <(fgrep -i -v "$command" <(crontab -u test -l)) <(echo "$job") | crontab -u test -
$ crontab -l
15 1 */2 * * cd && sh backupSQLToS3.sh
I missed to set the "directory" variable but your code works fine for me.
It looks like you are using the bourne shell (/bin/sh) to execute a bash script. Try using bash instead of sh.

Bash command substution error

The code:
`cat <(fgrep -i -v "$DAEMON_TEST" <(sudo -u asm crontab -l)) <(echo "$CRON") | sudo -u asm crontab -`
The error:
command substitution: line 46: syntax error near unexpected token `('
/etc/init.d/asm: command substitution: line 46: `cat <(fgrep -i -v "$DAEMON_TEST" <(sudo -u asm crontab -l)) <(echo "$CRON") | sudo -u asm crontab -'
The command runs fine when run directly into the shell by replacing the variables with the relevant strings
Here are the variables:
DAEMON_TEST=asm_test.php
CRON="*/15 * * * * /opt/asm/daemons/test.php"
The issue ended up being completely unrelated.
Changed:
#/bin/sh
to:
#/bin/bash
I never realized there would be a differnce
https://superuser.com/questions/125728/what-is-the-difference-between-bash-and-sh

Resources