Unix & Linux Stack Exchange
Q&A for users of Linux, FreeBSD and other Unix-like operating systems
Latest Questions
8
votes
6
answers
15038
views
How to catch and handle nonzero exit status within a Bash function?
Say I have the following (pointless) Bash function: myfunc() { ls failfailfail uptime } I run it as follows: myfunc || echo "Something is wrong." What I want to happen is `ls` runs (as it should), `failfailfail` does not work (since it doesn't exist), and `uptime` doesn't run. The return value of th...
Say I have the following (pointless) Bash function:
myfunc() {
ls
failfailfail
uptime
}
I run it as follows:
myfunc || echo "Something is wrong."
What I want to happen is
ls
runs (as it should), failfailfail
does not work (since it doesn't exist), and uptime
doesn't run. The return value of the function would be nonzero, and the error message would be shown. The return value doesn't have to be the exact exit status of the failed command, it just shouldn't be zero.
What actually happens is I get the output of ls
, followed by "-bash: failfailfail: command not found", followed by the output of uptime
. The error message is not shown, because the failed exit status is getting eaten.
set -e
has no useful effect, either within the function or in the scope where the function is called. The only way I can get this to work the way I want is:
myfunc() {
ls || return $?
failfailfail || return $?
uptime || return $?
}
But this seems awfully repetitive and ugly. Is there another way to clean this up?
smitelli
(308 rep)
Apr 28, 2016, 04:15 PM
• Last activity: Jun 23, 2025, 08:08 PM
0
votes
2
answers
79
views
Kill current bash shell and start a new one with some command
is it possible to kill/exit the current `bash` shell and start a new one with some command? Something like kill -9 $PPID && bash -c echo 'I started new!' which does not work obviously.
is it possible to kill/exit the current
bash
shell and start a new one with some command?
Something like
kill -9 $PPID && bash -c echo 'I started new!'
which does not work obviously.
Juergen
(101 rep)
Mar 18, 2025, 09:37 AM
• Last activity: Mar 18, 2025, 03:56 PM
532
votes
22
answers
282056
views
Get exit status of process that's piped to another
I have two processes `foo` and `bar`, connected with a pipe: $ foo | bar `bar` always exits 0; I'm interested in the exit code of `foo`. Is there any way to get at it?
I have two processes
foo
and bar
, connected with a pipe:
$ foo | bar
bar
always exits 0; I'm interested in the exit code of foo
. Is there any way to get at it?
Michael Mrozek
(95505 rep)
Jun 2, 2011, 08:19 PM
• Last activity: Jan 23, 2025, 06:50 PM
51
votes
4
answers
138513
views
How do I get the list of exit codes (and/or return codes) and meaning for a command/utility?
Is there a way I can do what stated in the title from the terminal commands, or will I have to look into the codes?
Is there a way I can do what stated in the title from the terminal commands, or will I have to look into the codes?
rusty
(1961 rep)
Jan 22, 2014, 07:14 AM
• Last activity: Jan 20, 2025, 09:40 PM
1
votes
2
answers
151
views
Bash script exits prematurely when calling another script inside it
I am trying to run a script which calls another script, but it does not seem to return to the script that called it. The source script "backup-plex.sh" calls “Linux_Plex_Backup.sh” (whilst passing an argument for the destination path). Once the script “Linux_Plex_Backup.sh” has been completed it sho...
I am trying to run a script which calls another script, but it does not seem to return to the script that called it.
The source script "backup-plex.sh" calls “Linux_Plex_Backup.sh” (whilst passing an argument for the destination path).
Once the script “Linux_Plex_Backup.sh” has been completed it should return to the original script "backup-plex.sh" and continue with the rsync command, but it doesn’t.
I call the source script using:
~/.backupScripts/./backup-plex.sh
Below is the source script which calls the script “Linux_Plex_Backup.sh” :
#!/bin/bash
# Define source path
source=/media/plex1
# Define destination paths
destination=/media/backPlex1ON
dest_plex_library=PlexLibraryBackup
echo "********************* Performing backup of Plex Media Library *********************"
# call plex library backup script
sudo -s ~/.backupScripts/PlexBackup/Linux_Plex_Backup.sh $destination/$dest_plex_library
echo "********************* Performing rsync backup of Plex 1 *********************"
# rsync command excludes
rsync_excludes="--exclude '*.ini' \
--exclude '*.DS_Store' \
--exclude '*._*' \
--exclude '**/\$RECYCLE.BIN' \
--exclude '**/\lost+found' \
--exclude '*.AppleDouble' \
--exclude '*.localized' \
--exclude '*.Trash-1000' \
--exclude '**/\PlexLibraryBackup'"
# rsync command options
rsync_cmd="/usr/local/bin/rsync"
rsync_options="-a --progress -l --delete $rsync_excludes"
eval $rsync_cmd $rsync_options $source $destination
Below is the “Linux_Plex_Backup.sh” script called by the source script …
#!/usr/bin/env bash
# shellcheck disable=SC2317,SC2181
#--------------------------------------------------------------------------
# Backup Linux Plex Database to tgz file in Backup folder.
# v1.1.6 04-Nov-2024 007revad
#
# MUST be run by a user in sudo, sudoers or wheel group, or as root
#
# To run the script:
# sudo -i /share/scripts/backup_linux_plex_to_tar.sh
# Change /share/scripts/ to the path where this script is located
#
# To do a test run on just Plex's profiles folder run:
# sudo -i /share/scripts/backup_linux_plex_to_tar.sh test
# Change /share/scripts/ to the path where this script is located
#
# Github: https://github.com/007revad/Linux_Plex_Backup
# Script verified at https://www.shellcheck.net/
#--------------------------------------------------------------------------
scriptver="v1.1.6"
script=Linux_Plex_Backup
if [ -z $1 ] ; then
echo "Argument missing: define destination path"
exit
fi
# Read variables from backup_linux_plex.config
Backup_Directory="$1" # JL: backup directory is passed as a parameter ($1) when Linux_Plex_Backup script is called
Name=""
LogAll=""
KeepQty=""
if [[ -f $(dirname -- "$0";)/backup_linux_plex.config ]];then
# shellcheck disable=SC1090,SC1091
while read -r var; do
if [[ $var =~ ^[a-zA-Z0-9_]+=.* ]]; then export "$var"; fi
done > "${Log_File}"
echo -e "$(basename -- "${Err_Log_File}")\n" |& tee -a "${Log_File}"
else
# Log and notify of backup success
echo -e "\nPlex backup completed successfully" |& tee -a "${Log_File}"
fi
exit "${arg1}"
}
trap cleanup EXIT
#--------------------------------------------------------------------------
# Check that script is running as root
if [[ $( whoami ) != "root" ]]; then
if [[ -d $Backup_Directory ]]; then
echo "ERROR: This script must be run as root!" |& tee -a "${Tmp_Err_Log_File}"
echo "ERROR: $( whoami ) is not root. Aborting." |& tee -a "${Tmp_Err_Log_File}"
else
# Can't log error to log file because $Backup_Directory does not exist
echo -e "\nERROR: This script must be run as root!"
echo -e "ERROR: $( whoami ) is not root. Aborting.\n"
fi
# Abort script because it isn't being run by root
exit 255
fi
#--------------------------------------------------------------------------
# "Plex Media Server" folder location
# ADM /volume1/Plex/Library/Plex Media Server
# DSM6 /volume1/Plex/Library/Application Support/Plex Media Server
# DSM7 /volume1/PlexMediaServer/AppData/Plex Media Server
# Linux /var/lib/plexmediaserver/Library/Application Support/Plex Media Server
# Set the Plex Media Server data location
Plex_Data_Path="/var/lib/plexmediaserver/Library/Application Support"
#--------------------------------------------------------------------------
# Check Plex Media Server data path exists
if [[ ! -d $Plex_Data_Path ]]; then
echo "Plex Media Server data path invalid! Aborting." |& tee -a "${Tmp_Err_Log_File}"
echo "${Plex_Data_Path}" |& tee -a "${Tmp_Err_Log_File}"
# Abort script because Plex data path invalid
exit 255
fi
#--------------------------------------------------------------------------
# Get Plex Media Server version
Version="$(/usr/lib/plexmediaserver/Plex\ Media\ Server --version)"
# Returns v1.29.2.6364-6d72b0cf6
# Plex version without v or hex string
Version=$(printf %s "${Version:1}"| cut -d "-" -f1)
# Returns 1.29.2.6364
#--------------------------------------------------------------------------
# Re-assign log names to include Plex version
# Backup filename
Backup_Name="${Nas}"_"${Now}"_Plex_"${Version}"_Backup
# If file exists already include time in name
BackupPN="$Backup_Directory/$Backup_Name"
if [[ -f $BackupPN.tgz ]] || [[ -f $BackupPN.log ]] || [[ -f "$BackupPN"_ERROR.log ]]; then
Backup_Name="${Nas}"_"${NowLong}"_Plex_"${Version}"_Backup
fi
# Log file filename
Log_File="${Backup_Directory}"/"${Backup_Name}".log
# Error log filename
Err_Log_File="${Backup_Directory}"/"${Backup_Name}"_ERROR.log
#--------------------------------------------------------------------------
# Start logging
echo -e "$script $scriptver\n" |& tee -a "${Log_File}"
# Log Linux distro, version and hostname
Distro="$(uname -a | awk '{print $2}')"
DistroVersion="$(uname -a | awk '{print $3}' | cut -d"-" -f1)"
echo "${Distro}" "${DistroVersion}" |& tee -a "${Log_File}"
echo "Hostname: $( hostname )" |& tee -a "${Log_File}"
# Log Plex version
echo Plex version: "${Version}" |& tee -a "${Log_File}"
#--------------------------------------------------------------------------
# Check if backup directory exists
if [[ ! -d $Backup_Directory ]]; then
echo "ERROR: Backup directory not found! Aborting backup." |& tee -a "${Log_File}" "${Tmp_Err_Log_File}"
# Abort script because backup directory not found
exit 255
fi
#--------------------------------------------------------------------------
# Stop Plex Media Server
echo "Stopping Plex..." |& tee -a "${Log_File}"
Result=$(systemctl stop plexmediaserver)
code="$?"
# Give sockets a moment to close
sleep 5
if [[ $code == "0" ]]; then
echo "Plex Media Server has stopped." |& tee -a "$Log_File"
else
echo "$Result" |& tee -a "$Log_File"
exit $code
fi
# Nicely terminate any residual Plex processes (plug-ins, tuner service and EAE etc)
###pgrep [Pp]lex | xargs kill -15 &>/dev/null
# Give sockets a moment to close
###sleep 5
# Kill any residual processes which DSM did not clean up (plug-ins and EAE)
Pids="$(ps -ef | grep -i 'plex plug-in' | grep -v grep | awk '{print $2}')"
[ "$Pids" != "" ] && kill -9 "$Pids"
Pids="$(ps -ef | grep -i 'plex eae service' | grep -v grep | awk '{print $2}')"
[ "$Pids" != "" ] && kill -9 "$Pids"
Pids="$(ps -ef | grep -i 'plex tuner service' | grep -v grep | awk '{print $2}')"
[ "$Pids" != "" ] && kill -9 "$Pids"
# Give sockets a moment to close
sleep 2
#--------------------------------------------------------------------------
# Check if all Plex processes have stopped
echo Checking status of Plex processes... |& tee -a "${Log_File}"
Response=$(pgrep -l plex)
# Check if plexmediaserver was found in $Response
if [[ -n $Response ]]; then
# Forcefully kill any residual Plex processes (plug-ins, tuner service and EAE etc)
pgrep [Pp]lex | xargs kill -9 &>/dev/null
sleep 5
# Check if plexmediaserver still found in $Response
Response=$(pgrep -l plex)
if [[ -n $Response ]]; then
echo "ERROR: Some Plex processes still running! Aborting backup."\
|& tee -a "${Log_File}" "${Tmp_Err_Log_File}"
echo "${Response}" |& tee -a "${Log_File}" "${Tmp_Err_Log_File}"
# Start Plex to make sure it's not left partially running
/usr/lib/plexmediaserver/Resources/start.sh
# Abort script because Plex didn't shut down fully
exit 255
else
echo "All Plex processes have stopped." |& tee -a "${Log_File}"
fi
else
echo "All Plex processes have stopped." |& tee -a "${Log_File}"
fi
#--------------------------------------------------------------------------
# Backup Plex Media Server
echo "=================================================" |& tee -a "${Log_File}"
echo "Backing up Plex Media Server data files..." |& tee -a "${Log_File}"
Exclude_File="$( dirname -- "$0"; )/plex_backup_exclude.txt"
# Check for test or error arguments
if [[ -n $1 ]] && [[ ${1,,} == "error" ]]; then
# Trigger an error to test error logging
Test="Plex Media Server/Logs/ERROR/"
echo "Running small error test backup of Logs folder" |& tee -a "${Log_File}"
elif [[ -n $1 ]] && [[ ${1,,} == "test" ]]; then
# Test on small Logs folder only
Test="Plex Media Server/Logs/"
echo "Running small test backup of Logs folder" |& tee -a "${Log_File}"
fi
# Check if exclude file exists
# Must come after "Check for test or error arguments"
if [[ -f $Exclude_File ]]; then
# Unset arguments
while [[ $1 ]]; do shift; done
# Set -X excludefile arguments for tar
set -- "$@" "-X"
set -- "$@" "${Exclude_File}"
else
echo "INFO: No exclude file found." |& tee -a "${Log_File}"
fi
# Use short variable names so tar command is not too long
BD="${Backup_Directory}"
BN="${Backup_Name}"
PDP="${Plex_Data_Path}"
LF="${Log_File}"
TELF="${Tmp_Err_Log_File}"
PMS="Plex Media Server"
# Run tar backup command
if [[ -n $Test ]]; then
# Running backup test or error test
if [[ ${LogAll,,} == "yes" ]]; then
echo "Logging all archived files" |& tee -a "${Log_File}"
tar -cvpzf "${BD}"/"${BN}".tgz -C "${PDP}" "${Test}" > >(tee -a "${LF}") 2> >(tee -a "${LF}" "${TELF}" >&2)
else
# Don't log all backed up files.
echo "Only logging errors" |& tee -a "${Log_File}"
tar -cvpzf "${BD}"/"${BN}".tgz -C "${PDP}" "${Test}" 2> >(tee -a "${LF}" "${TELF}" >&2)
fi
else
# Backup to tgz with PMS version and date in file name, send all output to shell and log, plus errors to error.log
# Using -C to change directory to "/share/Plex/Library/Application Support" to not backup absolute path
# and avoid "tar: Removing leading /" error
if [[ ${LogAll,,} == "yes" ]]; then
echo "Logging all archived files" |& tee -a "${Log_File}"
tar -cvpzf "${BD}"/"${BN}".tgz "$@" -C "${PDP}" "$PMS/" > >(tee -a "${LF}") 2> >(tee -a "${LF}" "${TELF}" >&2)
else
# Don't log all backed up files.
echo "Only logging errors" |& tee -a "${Log_File}"
tar -cvpzf "${BD}"/"${BN}".tgz "$@" -C "${PDP}" "$PMS/" 2> >(tee -a "${LF}" "${TELF}" >&2)
fi
fi
echo "Finished backing up Plex Media Server data files." |& tee -a "${Log_File}"
echo "=================================================" |& tee -a "${Log_File}"
#--------------------------------------------------------------------------
# Start Plex Media Server
echo "Starting Plex..." |& tee -a "${Log_File}"
#/usr/lib/plexmediaserver/Resources/start.sh
systemctl start plexmediaserver
#--------------------------------------------------------------------------
# Delete old backups
if [[ $KeepQty -gt "0" ]]; then
readarray -t array < <(ls "$Backup_Directory" |\
grep -E "${Nas}"'_[0-9]{8,}(-[0-9]{4,})?_Plex_.*\.tgz' | head -n -"$KeepQty")
if [[ "${#array[@]}" -gt "0" ]]; then
echo -e "\nDeleting old backups" |& tee -a "${Log_File}"
for file in "${array[@]}"; do
if [[ -f "$Backup_Directory/$file" ]]; then
echo "Deleting $file" |& tee -a "${Log_File}"
rm "$Backup_Directory/$file"
fi
if [[ -f "$Backup_Directory/${file%.tgz}.log" ]]; then
echo "Deleting ${file%.tgz}.log" |& tee -a "${Log_File}"
rm "$Backup_Directory/${file%.tgz}.log"
fi
if [[ -f "$Backup_Directory/${file%.tgz}_ERROR.log" ]]; then
echo "Deleting ${file%.tgz}_ERROR.log" |& tee -a "${Log_File}"
rm "$Backup_Directory/${file%.tgz}_ERROR.log"
fi
done
fi
fi
#--------------------------------------------------------------------------
# Append the time taken to stdout and log file
# End Time and Date
Finished=$( date )
# bash timer variable to log time taken to backup Plex
end="${SECONDS}"
# Elapsed time in seconds
Runtime=$(( end - start ))
# Append start and end date/time and runtime
echo -e "\nBackup Started: " "${Started}" |& tee -a "${Log_File}"
echo "Backup Finished:" "${Finished}" |& tee -a "${Log_File}"
# Append days, hours, minutes and seconds from $Runtime
printf "Backup Duration: " |& tee -a "${Log_File}"
printf '%dd:%02dh:%02dm:%02ds\n' \
$((Runtime/86400)) $((Runtime%86400/3600)) $((Runtime%3600/60))\
$((Runtime%60)) |& tee -a "${Log_File}"
#--------------------------------------------------------------------------
# Trigger cleanup function
exit 0
After running the scripts, the terminal window shows this...
Finished backing up Plex Media Server data files.
=================================================
Starting Plex...
Backup Started: Wed 8 Jan 09:29:21 GMT 2025
Backup Finished: Wed 8 Jan 09:33:17 GMT 2025
Backup Duration: 0d:00h:03m:56s
Plex backup completed successfully
username@homeserver:~$
In fact I have to press enter to get back to the command prompt, because it stays at " Plex backup completed successfully" until I press enter (is this a clue to the issue ?).
If the source script continued to run then I would expect to see the echo string (shown below) and the rsync command.
********************* Performing rsync backup of Plex 1 *********************"
Or is the issue anything to do with the fact that the source script starts with:
#!/bin/bash
and the script that's called starts with:
#!/usr/bin/env bash
UPDATE 08/01/25: I stripped most of “Linux_Plex_Backup.sh” to simplify it and it returns to the source script to run rsync. So there is something in “Linux_Plex_Backup.sh” thats causing the problem. The script was written by someone else and more advanced than my bash skills, so Im not sure whats causing it.
I tried commenting out "trap cleanup EXIT" as suggested but in made no difference
John
(47 rep)
Jan 7, 2025, 08:38 PM
• Last activity: Jan 14, 2025, 01:42 PM
132
votes
9
answers
100138
views
Preventing grep from causing premature termination of "bash -e" script
This script does not output `after`: #!/bin/bash -e echo "before" echo "anything" | grep e # it would if I searched for 'y' instead echo "after" exit I could solve this by removing the `-e` option on the shebang line, but I wish to keep it so my script stops if there is an error. I do not consider `...
This script does not output
after
:
#!/bin/bash -e
echo "before"
echo "anything" | grep e # it would if I searched for 'y' instead
echo "after"
exit
I could solve this by removing the -e
option on the shebang line, but I wish to keep it so my script stops if there is an error. I do not consider grep
finding no match as an error. How may I prevent it from exiting so abruptly?
iago-lito
(2931 rep)
Dec 15, 2016, 04:23 PM
• Last activity: Dec 5, 2024, 05:12 PM
0
votes
3
answers
151
views
My shell script exits if I try to mount from within the script an already mounted drive How can I make my shell script resume?
This is what happens. 1. I manually and successfully mount my USB drive using `mount /media/usb` from outside a shell script which I wrote. Therefore, the drive is working and mounted normally. 2. The very same mount command exists in this shell script. If I run this shell script while the USB drive...
This is what happens.
1. I manually and successfully mount my USB drive using
mount /media/usb
from outside a shell script which I wrote. Therefore, the drive is working and mounted normally.
2. The very same mount command exists in this shell script. If I run this shell script while the USB drive is mounted from outside the script, the script exits without executing the rest of the script by saying:
mount: /media/usb: /dev/sdc1 already mounted on /media/usb.
dmesg(1) may have more information after failed mount system call.`
3. If the drive is NOT mounted manually from outside the script like in bullet #1, the script does the mount and executes the rest of the commands inside the script without exiting the script.
So, the question is how to resume the script even though the drive was already mounted?
superlinux
(131 rep)
Aug 9, 2024, 06:53 AM
• Last activity: Aug 10, 2024, 07:23 AM
68
votes
3
answers
252871
views
Exit code at the end of a bash script
I am confused about the meaning of the exit code in the end of a bash script: I know that exit code 0 means that it finished successfully, and that there are many more exit codes numbers (127 if I'm not mistaken?) My question is about when seeing exit code 0 at the end of a script, does it force the...
I am confused about the meaning of the exit code in the end of a bash script:
I know that exit code 0 means that it finished successfully, and that there are many more exit codes numbers (127 if I'm not mistaken?)
My question is about when seeing exit code 0 at the end of a script, does it force the exit code as 0 even if the script failed or does it have another meaning?
soBusted
(941 rep)
Sep 6, 2016, 02:20 PM
• Last activity: Jun 29, 2024, 11:38 AM
2
votes
2
answers
1431
views
Bash scripting: Last line - "exit" - necessary?
another basic, innocent question: When you make a bash script, you could close it with, you could type in as last line of the script, ```exit```, ``` echo "Hello world!" exit ``` , is it advised, should one generally close a script with ```exit```? I could imagine, that basically from IT-security pe...
another basic, innocent question:
When you make a bash script, you could close it with, you could type in as last line
of the script,
,
echo "Hello world!"
exit
, is it advised, should one generally close a script with
?
I could imagine, that basically from IT-security perspective it's better to
set a definitive end to a script. I could imagine, that otherwise it would
be an open end, never closing, always luring in the background, and potentially
could be exploited somehow, or simply just wasting resources…
futurewave
(213 rep)
Jun 7, 2024, 05:37 PM
• Last activity: Jun 7, 2024, 06:02 PM
21
votes
5
answers
24655
views
Keep exit codes when trapping SIGINT and similar?
If I use `trap` like described e.g. on http://linuxcommand.org/wss0160.php#trap to catch ctrl-c (or similar) and cleanup before exiting then I am changing the exit code returned. Now this probably won't make difference in the real world (e.g. because the exit codes are not portable and on top of tha...
If I use
trap
like described e.g. on http://linuxcommand.org/wss0160.php#trap to catch ctrl-c (or similar) and cleanup before exiting then I am changing the exit code returned.
Now this probably won't make difference in the real world (e.g. because the exit codes are not portable and on top of that not always unambiguous as discussed in https://unix.stackexchange.com/questions/99112/default-exit-code-when-process-is-terminated) but still I am wondering whether there there is really no way to prevent that and return the default error code for interrupted scripts instead?
Example (in bash, but my question shouldn't be considered bash-specific):
#!/bin/bash
trap 'echo EXIT;' EXIT
read -p 'If you ctrl-c me now my return code will be the default for SIGTERM. ' _
trap 'echo SIGINT; exit 1;' INT
read -p 'If you ctrl-c me now my return code will be 1. ' _
Output:
$ ./test.sh # doing ctrl-c for 1st read
If you ctrl-c me now my return code will be the default for SIGTERM.
$ echo $?
130
$ ./test.sh # doing ctrl-c for 2nd read
If you ctrl-c me now my return code will be the default for SIGTERM.
If you ctrl-c me now my return code will be 1. SIGINT
EXIT
$ echo $?
1
(Edited to remove to make it more POSIX-conform.)
(Edited again to make it a bash script instead, my question is not shell-specific though.)
Edited to use the portable "INT" for trap in favor of the non-portable "SIGINT".
Edited to remove useless curly braces and add potential solution.
Update:
I solved it now by simply exiting with some error codes hardcoded and trapping EXIT. This might be problematic on certain systems because the error code might differ or the EXIT trap not possible but in my case it's OK enough.
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
phk
(6083 rep)
Oct 12, 2015, 12:26 PM
• Last activity: Jun 7, 2024, 01:03 PM
38
votes
3
answers
10156
views
How can I detect if I'm in a subshell?
I'm trying to write a function to replace the functionality of the `exit` builtin to prevent myself from exiting the terminal. I have attempted to use the `SHLVL` environment variable but it doesn't seem to change within subshells: $ echo $SHLVL 1 $ ( echo $SHLVL ) 1 $ bash -c 'echo $SHLVL' 2 My fun...
I'm trying to write a function to replace the functionality of the
exit
builtin to prevent myself from exiting the terminal.
I have attempted to use the SHLVL
environment variable but it doesn't seem to change within subshells:
$ echo $SHLVL
1
$ ( echo $SHLVL )
1
$ bash -c 'echo $SHLVL'
2
My function is as follows:
exit () {
if [[ $SHLVL -eq 1 ]]; then
printf '%s\n' "Nice try!" >&2
else
command exit
fi
}
----------
This won't allow me to use exit
within subshells though:
$ exit
Nice try!
$ (exit)
Nice try!
What is a good method to detect whether or not I am in a subshell?
jesse_b
(41447 rep)
Jun 12, 2019, 06:35 PM
• Last activity: May 8, 2024, 07:37 PM
13
votes
5
answers
25682
views
Exiting a shell script with nested loops
I have a shell script with nested loops and just found out that "exit" doesn't really exit the script, but only the current loop. Is there another way to completely exit the script on a certain error condition? I don't want to use "set -e", because there are acceptable errors and it would require to...
I have a shell script with nested loops and just found out that "exit" doesn't really exit the script, but only the current loop. Is there another way to completely exit the script on a certain error condition?
I don't want to use "set -e", because there are acceptable errors and it would require too much rewriting.
Right now, I am using kill to manually kill the process, but it seems there should be a better way to do this.
user923487
(303 rep)
Jun 30, 2015, 03:37 PM
• Last activity: Apr 10, 2024, 10:48 PM
32
votes
4
answers
25242
views
New parent process when the parent process dies
In UNIX, when a parent process disappears, I thought that all child processes reset init as their parent. Is this not correct all the time? Are there any exceptions?
In UNIX, when a parent process disappears, I thought that all child processes reset init as their parent. Is this not correct all the time? Are there any exceptions?
user100503
(497 rep)
Aug 8, 2014, 10:20 PM
• Last activity: Feb 24, 2024, 11:41 PM
9
votes
2
answers
8474
views
How can I run two commands in parallel and terminate them if ONE of them terminates with exit code 0?
I have 2 commands which are to be run simultaneously. And I want the script to terminate if one of them either exits with code 0 or 1. How can I achieve this in Linux(Ubuntu) cmd1 & cmd2 & wait
I have 2 commands which are to be run simultaneously. And I want the script to terminate if one of them either exits with code 0 or 1. How can I achieve this in Linux(Ubuntu)
cmd1 &
cmd2 &
wait
Sam
(91 rep)
Jan 10, 2017, 08:33 PM
• Last activity: Feb 16, 2024, 08:05 PM
3
votes
3
answers
7523
views
Difference between `exit;` and `exit $?;`
Is there any difference between these two commands: exec "$(dirname "$0")/suman-shell"; exit $?; and exec "$(dirname "$0")/suman-shell"; exit; is the `$?` redundant in the first case?
Is there any difference between these two commands:
exec "$(dirname "$0")/suman-shell";
exit $?;
and
exec "$(dirname "$0")/suman-shell";
exit;
is the
$?
redundant in the first case?
Alexander Mills
(10734 rep)
Nov 8, 2017, 04:27 PM
• Last activity: Jan 21, 2024, 02:21 PM
1
votes
3
answers
4188
views
How do you continue execution after using trap EXIT in bash?
**Environment:** GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20) I'm attempting to trap the exit from another function but then continue executing the program. In an object oriented language you could catch an exception and then continue execution without re-throwin; that is essentially...
**Environment:** GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20)
I'm attempting to trap the exit from another function but then continue executing the program. In an object oriented language you could catch an exception and then continue execution without re-throwin; that is essentially what I'm trying to do. I'm expecting the function
foo()
to exit
, but in this case I want to catch it and continue execution of the program.
#!/bin/bash
function doNotExitProgram()
{
echo "Ignoring EXIT"
# Magic happens here
}
trap doNotExitProgram EXIT
function foo()
{
echo "Inside foo()"
exit 170
}
foo
echo "Continue execution here"
Expected:
> Inside foo()
> Ignoring EXIT
> Continue execution here
Actual:
> Inside foo()
> Ignoring EXIT
**Steps tried so far:**
1. Tried using shopt -s extdebug
but that doesn't seem to work with EXIT.
2. Tried trap - EXIT
inside doNotExitProgram()
3. Tried trap - EXIT
return return 0
inside doNotExitProgram()
4. Tried trap - EXIT
return return 1
inside doNotExitProgram()
5. Tried return 0
inside doNotExitProgram()
6. Tried return 1
inside doNotExitProgram()
7. Tried trap "" EXIT
inside doNotExitProgram()
This scenario is not described on [Traps on tldp.org](https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html) or on the [trap man page](https://man7.org/linux/man-pages/man1/trap.1p.html) .
**EDIT:** If possible do not change foo()
Yzmir Ramirez
(165 rep)
Feb 16, 2022, 02:48 AM
• Last activity: Jan 15, 2024, 11:09 AM
16
votes
4
answers
23272
views
How can I skip the rest of a script without exiting the invoking shell, when sourcing the script?
I have a bash script, where I call `exit` somewhere to skip the rest of the script when `getopts` doesn't recognize an option or doesn't find an expected option argument. while getopts ":t:" opt; do case $opt in t) timelen="$OPTARG" ;; \?) printf "illegal option: -%s\n" "$OPTARG" >&2 echo "$usage" >...
I have a bash script, where I call
exit
somewhere to skip the rest of the script when getopts
doesn't recognize an option or doesn't find an expected option argument.
while getopts ":t:" opt; do
case $opt in
t)
timelen="$OPTARG"
;;
\?) printf "illegal option: -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
:) printf "missing argument for -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
esac
done
# reset of the script
I source
the script in a bash shell. When something is wrong, the shell exits.
Is there some way other than exit
to skip the rest of the script but without exiting the invoking shell?
Replacing exit
with return
doesn't work like for a function call, and the rest of the script will runs.
Thanks.
Tim
(106420 rep)
Aug 2, 2018, 02:45 PM
• Last activity: Nov 15, 2023, 11:39 PM
0
votes
1
answers
125
views
exit ssh when prompt for new password
I am looking for a way to exit ssh when password expires. I have a script that is checking few things on all VMs in infrastructure. Unfortunately there are few VMs with password auth method.
I am looking for a way to exit ssh when password expires.
I have a script that is checking few things on all VMs in infrastructure.
Unfortunately there are few VMs with password auth method.
saon
(11 rep)
Aug 11, 2023, 11:49 AM
• Last activity: Aug 11, 2023, 12:41 PM
2
votes
3
answers
6446
views
How to check if 'ls' outputs something... with a single command?
**TL/DR**: I'm working in Solaris 10. I have a `ls ... | egrep ...` command, and I need to know if it outputs any results or not. I could just add a `| wc -c` to the end; but I need the result (0 or non-zero) to be in the exit code, not in the output. And I can't use `if`, it's not a bash script, I...
**TL/DR**: I'm working in Solaris 10. I have a
ls ... | egrep ...
command, and I need to know if it outputs any results or not. I could just add a | wc -c
to the end; but I need the result (0 or non-zero) to be in the exit code, not in the output. And I can't use if
, it's not a bash script, I can only execute a single command.
---
**Long version**: I'm writing a maintenance process to compress and remove old log files in a Solaris 10 system. It checks all the .log or .xml files inside a given path, takes the ones which were last modified on a given month, creates a .tar with them, and then removes the original files:
ls -Egopqt /path/ | egrep -i '2016-10-[0-9] .*(\.log$|\.xml$)' | awk '{ print $7 }'
| xargs tar -cvf target.tar
And the same to remove the files, just replacing the last part with: | xargs -i rm {}
I'm probably overcomplicating it, but **it works. Unless there are no files** for a given month; if that's the case, I get an error saying tar: Missing filenames
. How can I check it before attempting to create the tar? I thought of something like this, using wc to check if there is an output or not :
ls ... | egrep ... | wc -c
Which correctly outputs 0
when there aren't any files, and another number otherwise. The problem is: **I can't see the output, only the exit code** (which is always 0 since there is no error). I'm not doing this in a bash script, I'm working with Siebel CRM: I have a javascript function which generates the commands and executes them with Clib.system calls. The only thing I can see is the exit code: 0
for OK, non-zero for an error (I see the actual number, not "non-zero").
Previously I had a similar requeriment, to check if a *single* file exists or not, and this answer helped me to get to this:
[ -f filename ] && exit 111 || exit 0
I'm successfully getting either 111
or 0
, depending on if filename exists or not. But I can't get it to work with the ls ... | egrep ... | wc
command. I've tried using this syntax :
[[ $( ls -Egopq /path/ | egrep -i ... | wc -c ) -ne 0 ]] && exit 111 || exit 0
But I'm getting always exit code 2, it doesn't matter if there are files or not. What am I doing wrong?
---
PS: I know I could write a tiny shell script to perform the checks, use a simple if
to compare the output, and then return whatever exit code I want. Also, I actually *can* access a command's output, I'd just need to redirect it to a > tempfile
and then read it from Siebel. However, I'd prefer to avoid both of these options, as I'm trying to avoid creating unnecessary (temp or permanent) files.
AJPerez
(133 rep)
Nov 22, 2016, 05:25 PM
• Last activity: Jul 28, 2023, 12:08 PM
83
votes
4
answers
105632
views
Default exit code when process is terminated?
When a process is killed with a handle-able signal like `SIGINT` or `SIGTERM` but it does not handle the signal, what will be the exit code of the process? What about for unhandle-able signals like `SIGKILL`? From what I can tell, killing a process with `SIGINT` likely results in exit code `130`, bu...
When a process is killed with a handle-able signal like
SIGINT
or SIGTERM
but it does not handle the signal, what will be the exit code of the process?
What about for unhandle-able signals like SIGKILL
?
From what I can tell, killing a process with SIGINT
likely results in exit code 130
, but would that vary by kernel or shell implementation?
$ cat myScript
#!/bin/bash
sleep 5
$ ./myScript
$ echo $?
130
I'm not sure how I would test the other signals...
$ ./myScript &
$ killall myScript
$ echo $?
0 # duh, that's the exit code of killall
$ killall -9 myScript
$ echo $?
0 # same problem
Cory Klein
(19341 rep)
Nov 6, 2013, 05:42 PM
• Last activity: May 8, 2023, 10:00 AM
Showing page 1 of 20 total questions