How to output return code in shell? - linux

I'm trying to call a custom shell script through sh:
/bin/sh -c 'myscript.sh` >log.txt 2>&1 & echo $!
Output of this command is a PID of a created background process. I want to instruct /bin/sh to save return code of myscript.sh to some file. Is it possible?

echo $? >> /path/to/return_code
$? has the return code of the last statement in bash.

(/bin/sh -c "myscript.sh" >log.txt 2>&1 ; echo $? >somefile) & echo $!

(
/bin/sh -c 'myscript.sh` >log.txt 2>&1
echo $? > some_file
) &

Related

How to pass IF statement into SSH in UNIX?

I have the following bash script:
#!/bin/bash
set command "pgrep -x 'gedit' "
ssh -t test#192.168.94.139 $command
Now, I want to include this as well in the other device:
if pgrep -x "gedit" > /dev/null
then
echo "Running"
else
echo "Not Running"
fi
How can I make the IF Statement run on the other device? I wasn't able to include it in the ssh.
I tried this:
set command "pgrep -x 'gedit' "
ssh -t test#192.168.94.139 '
if pgrep -x "gedit" > /dev/null
then
echo "Running"
else
echo "Not Running"
fi'
But it didn't work! maybe because there is no command at the beginning?
Thanks.
Invoke bash with heredoc:
ssh -t test#192.168.94.139 bash <<EOF
if pgrep -x "gedit" > /dev/null
then
echo "Running"
else
echo "Not Running"
fi
EOF

Propagate exit code from runuser command

I want to run the bash script, StartSomething.sh, as a specific user. I use runuser command for that. Also I want to know an exit code from this bash script. So I write an exit code to the file when the command is finished or interrupted. Here is the code:
runuser myuser -s /bin/bash -c "./StartSomething.sh --pidfile=${pidfile}; \
echo $? > ${statusfile};" &
sleep 5
pid=$(cat ${pidfile})
while ps -p ${pid} > /dev/null; do sleep 1; done
end=$(cat ${statusfile})
echo "End code: ${end}"
exit ${end}
Problem is that exit code is still 0, though bash script is interrupted. What can be wrong?
If I have separate file, start.sh, with this code:
./StartSomething.sh --pidfile=${pidfile}
echo $? > ${statusfile}
and runuser command look like this:
runuser myuser -s /bin/bash -c "./start.sh" &
everything is working fine. I want to use first example without separate file. Can someone tell me what can be wrong? Is there better solution for this problem?
If all you want to do is to run the program in the background, and wait for it to finish, I think you could also use wait to get the return value (runuser passes it through, unless something exceptional happens):
runuser myuser ./StartSomething.sh --pidfile=${pidfile} &
pid=$!
# do something else
wait $!
echo "it returned $?"
or
runuser myuser ./StartSomething.sh --pidfile=${pidfile} &
pid=$!
echo -n "waiting"
while kill -0 $pid 2>/dev/null; do
echo -n "."
sleep 1
done
echo
wait $!
echo "it returned $?"
There is problem with escaping special character $. Correct command:
runuser myuser -s /bin/bash -c "./StartSomething.sh --pidfile=${pidfile}; \
echo \$? > ${statusfile};" &
Replace $? with \$?.

get return value of command run with script -c

Is there a way to capture the return value of a program run using script -c?
For example (in bash)
/bin/false; echo $? # outputs 1
/usr/bin/script -c "/bin/false" /dev/null; echo $?
# outputs 0 as script exited successfully.
I need to get the return value from /bin/false instead of from /usr/bin/script.. is this possible? I'm using script to trick a program into thinking it is running in a real tty even though it isn't... Thanks!
According to man script, using -e option will return the exit code of the child process.
-e, --return
Return the exit code of the child process.
Uses the same format as bash termination
on signal termination exit code is 128+n.
Here's some example.
$ /usr/bin/script -e -c "/bin/false" /dev/null; echo $?
1
$ /usr/bin/script -e -c "/bin/true" /dev/null; echo $?
0
$ /usr/bin/script -e -c "exit 123" /dev/null; echo $?
123

how to check whether one instance of shell script is already running - Linux

I have two different shell script say like
a.sh
b.sh
**code of a.sh**
#!/system/bin/sh
#some code
./xyz/b.sh &
Here we can see i am running b.sh through a.sh file which is postboot script. Each time when device gets reboot it is adding ./xyz/b.sh & which i am trying to avoid.
what i am trying to do :
i need to write a code in such a way that will find if ./system/xyz/b.sh & is already there then no need to add again.
Code :
if pgrep /xyz/b.sh > /dev/null 2>&1
then
echo aplog is running
exit 1
fi
these code is not running. Do not know where i am doing mistake.
Just try:
pgrep b.sh > /dev/null 2>&1
if [ 0 == $? ]
then
...
fi
pgrep will only work on process name, not full path to process name.
Try pgrep -f b.sh or pgrep -x b.sh instead of pgrep -x /xyz/b.sh
Hi test your file existence before creating it with:
filename="/fullpath/xyz/b.sh"
if [ -f "$filename" ]
then
echo "$filename found"
else
echo "$filename not found."
fi

Why this bash script can't get the pid of the background process by $!

I have a script like that:
su lingcat -c PHPRC\=\/home\/lingcat\/etc\/php5\
PHP_FCGI_CHILDREN\=4\ \/usr\/bin\/php\-loop\.pl\ \/usr\/bin\/php5\-cgi\ \-b\
127\.0\.0\.1\:9006\ \>\>\/home\/lingcat\/logs\/php\.log\ 2\>\&1\ \<\/dev\/null\ \&\
echo\ \$\!\ \>\/var\/php\-nginx\/135488849520817\.php\.pid
This is working. But there is too many \ in the script, they make the code unreadable. So, I wrote a new shell script:
#!/bin/sh
case "$1" in
'start')
su biergaizi -c "PHPRC=/home/biergaizi/etc/php5 PHP_FCGI_CHILDREN=2
/usr/bin/php-loop.pl /usr/bin/php-cgi -b /var/run/virtualhost/php5-fpm-biergaizi.test.sock >>/home/biergaizi/logs/php.log 2>&1 </dev/null &
echo $! > /var/php-nginx/biergaizi.test.php.pid"
RETVAL=$?
;;
'stop')
su biergaizi -c "kill `cat /var/php-nginx/biergaizi.test.php.pid` ; sleep 1"
RETVAL=$?
;;
'restart')
$0 stop ; $0 start
RETVAL=$?
;;
*)
echo "Usage: $0 { start | stop }"
RETVAL=1
;;
esac
exit
But /var/php-nginx/biergaizi.test.php.pid is empty.
What's wrong?
The .pid file is empty, because $! gets substituted by the shell executing your script, instead of the shell executing the commands you pass through su. And as there is no recently started background command in your script, it substitutes an empty string. So, shell started by su executes simply echo > /var/php-nginx/biergaizi.test.php.pid.
To prevent that, quote your command passed to su using single quotes, instead of double quotes. It is better to do that to the "stop" command as well. Like this:
su biergaizi -c 'PHPRC=/home/biergaizi/etc/php5 PHP_FCGI_CHILDREN=2
/usr/bin/php-loop.pl /usr/bin/php-cgi -b /var/run/virtualhost/php5-fpm-biergaizi.test.sock >>/home/biergaizi/logs/php.log 2>&1 </dev/null &
echo $! > /var/php-nginx/biergaizi.test.php.pid'
And this:
su biergaizi -c 'kill `cat /var/php-nginx/biergaizi.test.php.pid` ; sleep 1'
See http://www.gnu.org/software/bash/manual/html_node/Quoting.html for details.
try this:
Escape $ from $!, before passing to su -c.

Resources