How to return the exit code? Error: return: Reading: numeric argument required
Solution 1
Bash's return()
can only return numerical arguments. In any case, by default, it will return the exit status of the last command run. So, all you really need is:
#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
sudo apt-get install --assume-yes $@
fi
}
You don't need to explicitly set a value to be returned since by default a function will return $?
. However, that will not work if the first apt
command failed and you did not go into the if
loop. To make it more robust, use this:
#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
ret=$?
if [ $ret -eq 0 ] ; then
## If this is executed, the else is ignored and $? will be
## returned. Here, $?will be the exit status of this command
sudo apt-get install --assume-yes $@
else
## Else, return the exit value of the first apt-get
return $ret
fi
}
The general rule is that in order to have a function return the exit status of a particular job and not necessarily the last one it ran, you will need to save the exit status to a variable and return the variable:
function foo() {
run_a_command arg1 arg2 argN
## Save the command's exit status into a variable
return_value= $?
[the rest of the function goes here]
## return the variable
return $return_value
}
EDIT: Actually, as @gniourf_gniourf pointed out in the comments, you could greatly simplify the whole thing using &&
:
install_auto() {
apt-get -h > /dev/null 2>&1 &&
sudo apt-get install --assume-yes $@
}
The return value of this function will be one of:
- If
apt-get -h
failed, it will return its exit code - If
apt-get -h
succeeded, it will return the exit code ofsudo apt-get install
.
Solution 2
For completeness, here is my actual function with some modifications as suggested by @terdon and @gniourf_gniourf :
install_auto() {
if [ ! $# -gt 0 ] ; then
echo "usage: $0 package_name [package_name ...]"
fi
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
if [ -f "$@" ] || [[ "$@" =~ '/' ]] ; then
sudo gdebi -n "$@"
return $?
else
sudo apt-get install --assume-yes "$@"
return $?
fi
fi
zypper help > /dev/null 2>&1
if [ $? -eq 0 ] ; then
sudo zypper --non-interactive --no-gpg-checks --quiet install --auto-agree-with-licenses "$@"
return $?
fi
#may check other package managers in the future
echo "ERROR: package manager not found"
return 255
}
I appreciate any further suggestions.
Related videos on Youtube
Jarek
You may be interested in the story of SE moderator Monica Cellio and how she was unfairly treated by the corporate management of this site. More info here. An update is available. Let's hope we can cultivate a more fair environment for content creators and moderators going forward.
Updated on September 18, 2022Comments
-
Jarek almost 2 years
Here's a simplified version of my script. My question is, How do I return the exit code from
apt-get
in this case?#!/bin/bash install_auto() { apt-get -h > /dev/null 2>&1 if [ $? -eq 0 ] ; then return $(sudo apt-get install --assume-yes $@) fi return 1 } echo "installing $@" install_auto "$@" echo $? echo "finished" exit 0
The output is:
./install_test.sh: line 5: return: Reading: numeric argument required
Update: I came up with something that works:
return $(sudo apt-get install --assume-yes "$@" >/dev/null 2>&1; echo $?)
Is that a good approach?
-
Jarek almost 11 yearsSorry, my example was not clear enough. I need a return statement (or some equivalent logic) in my actual script so stuff following this statement is not executed if apt-get was present on this system. If apt-get is not present, it looks for zypper, etc. I guess adding
return $?
on the next line of your example aftersudo apt-get ...
might be sufficient. Is that right? Thanks -
terdon almost 11 years@MountainX see updated answer. The way you have written it (and the way I have written my example) if the
apt
fails, then its exit status is returned and the function exits, returning the exit value of theat-get
. Isn't that what you need? -
terdon almost 11 years@gniourf_gniourf yes indeed, answer updated.
-
Jarek almost 11 yearsThanks for the feedback. I pasted my complete function as I realized that my simplified example wasn't enough. I appreciate any further comments.
-
user almost 11 yearsShouldn't that be && \ ...?
-
terdon almost 11 years@MichaelKjörling not in a script, no.
-
tripleee almost 11 yearsThe
cmd; if [ $? -eq 0 ]; then ...
construct is generally better expressed asif cmd; then ...
or even justcmd && ...
if the "then" part is just a simple command.