I am trying to get the exit code of a command launched via x-terminal-emulator -e
. Using this command, it simply opens a new terminal window and passes it sh -c
with the command that you want to be executed within the new terminal window. I then use a combination of ps ax, grep, xargs
& cut
to get the PID of the running process.
#!/bin/bash
execute() {
local -r CMDS="$1"
local exitCode=0
local cmdsPID=""
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Execute a command within a
# a new 'x-terminal-emulator' window.
x-terminal-emulator -e "$CMDS" &> /dev/null
# Get the PID of the process spawned by
# 'x-terminal-emulator'.
cmdsPID="$(ps ax | grep "sh -c $CMDS" | xargs | cut -d ' ' -f 1)"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Wait for the commands to no longer be executing
# in the background, and then get their exit code.
wait "$cmdsPID" &> /dev/null
exitCode=$?
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Print output based on what happened.
echo "$exitCode"
}
execute "apt update && apt upgrade -y && apt full-upgrade -y && apt autoremove -y && apt clean"
However, when I utilize the command wait
to wait for the PID to finish running so that I can get the exit code of the command, wait
returns:
pid #### is not a child of this shell
Is there a way where I can both wait for the PID to finish, then grab its exit code from a process not spawned under the parent shell?
After a bit of trial and error and some research, I have come up with a solution.
My solution involves the following:
$?
output from within the new terminal window that was spawned from x-terminal-emulator
to a temporary file utilizing mktemp
.until
conditional structure to wait until that temporary file is not empty.cat
the contents of the file and store it within a variable. Then, echo
the results.#!/bin/bash
execute() {
local -r CMDS="$1"
local -r EXIT_STATUS_FILE="$(mktemp /tmp/XXXXX)"
local exitCode=0
local cmdsPID=""
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Execute a command within a
# a new 'x-terminal-emulator' window.
x-terminal-emulator -e "($CMDS) ; echo \$? > $EXIT_STATUS_FILE" \
&> /dev/null
# Get the PID of the process spawned by
# 'x-terminal-emulator'.
cmdsPID="$(ps ax | grep -v "grep" | grep -v "S+" | grep "sh -c" | grep "$CMDS" | xargs | cut -d ' ' -f 1)"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Wait for the commands to no longer be executing
# in the background, and then get their exit code.
until [ -s "$EXIT_STATUS_FILE" ];
do
sleep 1
done
exitCode="$(cat "$EXIT_STATUS_FILE")"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Print output based on what happened.
echo "$exitCode"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Remove temporary file.
rm -rf "$EXIT_STATUS_FILE"
}
execute \
"apt update && apt upgrade -y && apt full-upgrade -y && apt autoremove -y && apt clean"