Linux shell script: Run a program only if it exists, ignore it if it does not exist
Clash Royale CLAN TAG#URR8PPP
I am programming a Linux shell script that will print status banners during its execution only if the proper tool, say figlet
, is installed (this is: reachable on system path).
Example:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
I would like for my script to work without errors even when figlet
is not installed.
What could be a practical method?
shell scripting executable
add a comment |
I am programming a Linux shell script that will print status banners during its execution only if the proper tool, say figlet
, is installed (this is: reachable on system path).
Example:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
I would like for my script to work without errors even when figlet
is not installed.
What could be a practical method?
shell scripting executable
1
stackoverflow.com/questions/592620/…
– gip
Jan 29 at 19:22
@sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.
– Sopalajo de Arrierez
Jan 30 at 10:50
2
The title to this question got me in all sorts of metaphysical problems
– g_uint
Jan 30 at 12:31
2
Do you want to ignore all errors? Just usefiglet ... || true
.
– Giacomo Alzetta
Jan 30 at 13:40
If you don’t care about exit codes a shortcut is to usefiglet || true
, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.
– eckes
Jan 31 at 1:26
add a comment |
I am programming a Linux shell script that will print status banners during its execution only if the proper tool, say figlet
, is installed (this is: reachable on system path).
Example:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
I would like for my script to work without errors even when figlet
is not installed.
What could be a practical method?
shell scripting executable
I am programming a Linux shell script that will print status banners during its execution only if the proper tool, say figlet
, is installed (this is: reachable on system path).
Example:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
I would like for my script to work without errors even when figlet
is not installed.
What could be a practical method?
shell scripting executable
shell scripting executable
edited Jan 30 at 9:30
Gilles
538k12810881605
538k12810881605
asked Jan 29 at 19:11
Sopalajo de ArrierezSopalajo de Arrierez
1,75993563
1,75993563
1
stackoverflow.com/questions/592620/…
– gip
Jan 29 at 19:22
@sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.
– Sopalajo de Arrierez
Jan 30 at 10:50
2
The title to this question got me in all sorts of metaphysical problems
– g_uint
Jan 30 at 12:31
2
Do you want to ignore all errors? Just usefiglet ... || true
.
– Giacomo Alzetta
Jan 30 at 13:40
If you don’t care about exit codes a shortcut is to usefiglet || true
, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.
– eckes
Jan 31 at 1:26
add a comment |
1
stackoverflow.com/questions/592620/…
– gip
Jan 29 at 19:22
@sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.
– Sopalajo de Arrierez
Jan 30 at 10:50
2
The title to this question got me in all sorts of metaphysical problems
– g_uint
Jan 30 at 12:31
2
Do you want to ignore all errors? Just usefiglet ... || true
.
– Giacomo Alzetta
Jan 30 at 13:40
If you don’t care about exit codes a shortcut is to usefiglet || true
, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.
– eckes
Jan 31 at 1:26
1
1
stackoverflow.com/questions/592620/…
– gip
Jan 29 at 19:22
stackoverflow.com/questions/592620/…
– gip
Jan 29 at 19:22
@sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.
– Sopalajo de Arrierez
Jan 30 at 10:50
@sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.
– Sopalajo de Arrierez
Jan 30 at 10:50
2
2
The title to this question got me in all sorts of metaphysical problems
– g_uint
Jan 30 at 12:31
The title to this question got me in all sorts of metaphysical problems
– g_uint
Jan 30 at 12:31
2
2
Do you want to ignore all errors? Just use
figlet ... || true
.– Giacomo Alzetta
Jan 30 at 13:40
Do you want to ignore all errors? Just use
figlet ... || true
.– Giacomo Alzetta
Jan 30 at 13:40
If you don’t care about exit codes a shortcut is to use
figlet || true
, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.– eckes
Jan 31 at 1:26
If you don’t care about exit codes a shortcut is to use
figlet || true
, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.– eckes
Jan 31 at 1:26
add a comment |
8 Answers
8
active
oldest
votes
My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:
figlet()
command -v figlet >/dev/null && command figlet "$@"
Then you can have figlet arg1 arg2...
unchanged in your script.
@Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):
if ! command -v figlet > /dev/null; then figlet() :; ; fi
If you'd like the arguments to figlet
to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:
if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi
1
Where doescommand
come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).
– eewanco
Jan 29 at 22:38
1
@eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.
– Jeff Schaller
Jan 29 at 23:09
3
command
is a POSIX Bourne shell builtin. It normally executes the command provided, but the-v
flag makes it behave more liketype
, another shell builtin.
– wyrm
Jan 30 at 1:29
@eewancotype -a command
will show you.which
will only show executables on your$PATH
, not built-ins, keywords, functions or aliases.
– l0b0
Jan 30 at 1:38
@l0b0: on RedHat-family with bash and the default profile(s)which
does find an applicable alias, because it aliaseswhich
itself to run/usr/bin/which
and pipe it a list of the shell's aliases to look in (!) (Of coursewhich
suppresses the alias and uses only the program, which doesn't show aliases.)
– dave_thompson_085
Jan 31 at 14:43
add a comment |
You can test to see if figlet
exists
if type figlet >/dev/null 2>&1
then
echo Figlet is installed
fi
add a comment |
A common way to do this is with test -x
aka [ -x
. Here is an example taken from /etc/init.d/ntp
on a Linux system:
if [ -x /usr/bin/lockfile-create ]; then
lockfile-create $LOCKFILE
lockfile-touch $LOCKFILE &
LOCKTOUCHPID="$!"
fi
This variant relies on knowing the full path of the executable. In /bin/lesspipe
I found an example which works around that by combining -x
and the which
command:
if [ -x "`which bunzip`" ]; then bunzip -c "$1"
else echo "No bunzip available"; fi ;;
That way this will work without knowing in advance where in the PATH
the bunzip
executable is.
4
Don't usewhich
. And even ifwhich
worked, usingtest -x
on its output is silly: if you get a path fromwhich
, it exists.
– Gilles
Jan 30 at 9:29
1
@Gilles: Technically speaking,test -x
does more than just check if a file exists (that's whattest -e
is for). It also checks if the file has the execute permissions set.
– comfreak
Feb 1 at 19:19
@comfreak So doeswhich
.
– Gilles
Feb 1 at 20:25
add a comment |
At the start of your script, check if figlet
exists, and if it does not, define a shell function that does nothing:
type figlet >/dev/null 2>&1 || figlet() :;
type
checks if figlet
exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1
discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :;
defines figlet
as a function that does nothing.
This way you don't have to edit every line of your script that uses figlet
, or check if it exists every time figlet
is called.
You can add a diagnostic message, if you like:
type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ;
As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.
I like the simplicity of this answer. You could also replacetype figlet >/dev/null 2>&1
withhash figlet 2>/dev/null
if you're using bash. (The OP said "if it's in my PATH".)
– Joe
Feb 1 at 21:44
add a comment |
Another alternative -- a pattern I've seen in project auto configure scripts:
if [ -x /usr/bin/figlet ]
then
FIGLET=/usr/bin/figlet
else
FIGLET=:
fi
$FIGLET "Hello, world!"
In your specific case you could even do,
if [ -x /usr/bin/figlet ]
then
SAY=/usr/bin/figlet
elif [ -x /usr/local/bin/figlet ]
then
SAY=/usr/local/bin/figlet
elif [ -x /usr/bin/banner ]
then
SAY=/usr/bin/banner
else
SAY=/usr/bin/echo
fi
$SAY "Hello, world!"
If you don't know the specific path, you can try multiple elif
(see above) to try known locations, or just use the PATH
to always resolve the command:
if command -v figlet >/dev/null
then
SAY=figlet
elif command -v banner >/dev/null
then
SAY=banner
else
SAY=echo
fi
In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH
, perhaps in their own ~/bin
.
If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin
that might or might not be the command I expected.
3
What iffiglet
was in/usr/local/bin
or/home/bob/stuff/programs/executable/figlet
?
– Gilles
Jan 30 at 9:30
add a comment |
type -p figlet > /dev/null && figlet "foo"
The bash type
command finds a command, function, alias, keyword, or builtin (see help type
) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet
in the path (-p
means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null
does), and if it returns true (&&
), it will execute figlet
.
This is simpler if figlet
is in a fixed location:
[ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"
Here we're using the test
command (a.k.a. [
) to see if /usr/bin/figlet
is executable (-x
) and if so (&&
) execute it. This solution I think is more portable than using type
which is a bashism I believe.
You could make a function that does this for you:
function x()
if type -p "$1" >/dev/null; then
cmd="$1"
shift
"$cmd" "$@"
fi
(The quotes are necessary owing to potential spaces)
Then you'd just do:
x figlet "foo"
add a comment |
o/,
I would say something like
#!/usr/bin/env bash
# if figlet is installed :
if [ "$(which figlet 2>/dev/null)" ]; then
# do what you wanted to do
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
# if not
else
# exit program with an error
echo "please install figlet"
exit 1
fi
add a comment |
You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.
if figlet --help >/dev/null 2>&1 ; then
# figlet is available
echo "foo"
figlet "starting"
#etc
else
rc=$?
echo "figlet is not installed or not working correctly (return code $rc)"
fi
Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do
figlet --help >/dev/null 2>&1
rc=$?
if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
echo "command figlet not found"
else
figlet "whatever" # use figlet
fi
The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.
– Chris
Jan 31 at 11:15
If you really want to test only for its installation, then you want to test if$?
equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, ifcommand --help
fails, then the installation is borked sufficiently that it might as well not be there!.
– nigel222
Jan 31 at 12:06
1
126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on--help
being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it.at --help
fails withat: invalid option -- '-'
, for instance, and an exit status of130
on my system.
– Chris
Jan 31 at 12:47
Also, of course, if figlet can exit with status 127 that could be a problem too.
– Chris
Jan 31 at 15:14
Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as-?
--help
--version
... or you could find out whatfiglet -0 --illegal
exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).
– nigel222
Jan 31 at 15:29
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f497526%2flinux-shell-script-run-a-program-only-if-it-exists-ignore-it-if-it-does-not-ex%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:
figlet()
command -v figlet >/dev/null && command figlet "$@"
Then you can have figlet arg1 arg2...
unchanged in your script.
@Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):
if ! command -v figlet > /dev/null; then figlet() :; ; fi
If you'd like the arguments to figlet
to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:
if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi
1
Where doescommand
come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).
– eewanco
Jan 29 at 22:38
1
@eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.
– Jeff Schaller
Jan 29 at 23:09
3
command
is a POSIX Bourne shell builtin. It normally executes the command provided, but the-v
flag makes it behave more liketype
, another shell builtin.
– wyrm
Jan 30 at 1:29
@eewancotype -a command
will show you.which
will only show executables on your$PATH
, not built-ins, keywords, functions or aliases.
– l0b0
Jan 30 at 1:38
@l0b0: on RedHat-family with bash and the default profile(s)which
does find an applicable alias, because it aliaseswhich
itself to run/usr/bin/which
and pipe it a list of the shell's aliases to look in (!) (Of coursewhich
suppresses the alias and uses only the program, which doesn't show aliases.)
– dave_thompson_085
Jan 31 at 14:43
add a comment |
My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:
figlet()
command -v figlet >/dev/null && command figlet "$@"
Then you can have figlet arg1 arg2...
unchanged in your script.
@Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):
if ! command -v figlet > /dev/null; then figlet() :; ; fi
If you'd like the arguments to figlet
to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:
if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi
1
Where doescommand
come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).
– eewanco
Jan 29 at 22:38
1
@eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.
– Jeff Schaller
Jan 29 at 23:09
3
command
is a POSIX Bourne shell builtin. It normally executes the command provided, but the-v
flag makes it behave more liketype
, another shell builtin.
– wyrm
Jan 30 at 1:29
@eewancotype -a command
will show you.which
will only show executables on your$PATH
, not built-ins, keywords, functions or aliases.
– l0b0
Jan 30 at 1:38
@l0b0: on RedHat-family with bash and the default profile(s)which
does find an applicable alias, because it aliaseswhich
itself to run/usr/bin/which
and pipe it a list of the shell's aliases to look in (!) (Of coursewhich
suppresses the alias and uses only the program, which doesn't show aliases.)
– dave_thompson_085
Jan 31 at 14:43
add a comment |
My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:
figlet()
command -v figlet >/dev/null && command figlet "$@"
Then you can have figlet arg1 arg2...
unchanged in your script.
@Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):
if ! command -v figlet > /dev/null; then figlet() :; ; fi
If you'd like the arguments to figlet
to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:
if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi
My interpretation would use a wrapper function named the same as the tool; in that function, execute the real tool if it exists:
figlet()
command -v figlet >/dev/null && command figlet "$@"
Then you can have figlet arg1 arg2...
unchanged in your script.
@Olorin came up with a simpler method: define a wrapper function only if we need to (if the tool doesn't exist):
if ! command -v figlet > /dev/null; then figlet() :; ; fi
If you'd like the arguments to figlet
to be printed even if figlet isn't installed, adjust Olorin's suggestion as follows:
if ! command -v figlet > /dev/null; then figlet() printf '%sn' "$*"; ; fi
edited Jan 31 at 14:53
answered Jan 29 at 20:20
Jeff SchallerJeff Schaller
41.7k1156132
41.7k1156132
1
Where doescommand
come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).
– eewanco
Jan 29 at 22:38
1
@eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.
– Jeff Schaller
Jan 29 at 23:09
3
command
is a POSIX Bourne shell builtin. It normally executes the command provided, but the-v
flag makes it behave more liketype
, another shell builtin.
– wyrm
Jan 30 at 1:29
@eewancotype -a command
will show you.which
will only show executables on your$PATH
, not built-ins, keywords, functions or aliases.
– l0b0
Jan 30 at 1:38
@l0b0: on RedHat-family with bash and the default profile(s)which
does find an applicable alias, because it aliaseswhich
itself to run/usr/bin/which
and pipe it a list of the shell's aliases to look in (!) (Of coursewhich
suppresses the alias and uses only the program, which doesn't show aliases.)
– dave_thompson_085
Jan 31 at 14:43
add a comment |
1
Where doescommand
come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).
– eewanco
Jan 29 at 22:38
1
@eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.
– Jeff Schaller
Jan 29 at 23:09
3
command
is a POSIX Bourne shell builtin. It normally executes the command provided, but the-v
flag makes it behave more liketype
, another shell builtin.
– wyrm
Jan 30 at 1:29
@eewancotype -a command
will show you.which
will only show executables on your$PATH
, not built-ins, keywords, functions or aliases.
– l0b0
Jan 30 at 1:38
@l0b0: on RedHat-family with bash and the default profile(s)which
does find an applicable alias, because it aliaseswhich
itself to run/usr/bin/which
and pipe it a list of the shell's aliases to look in (!) (Of coursewhich
suppresses the alias and uses only the program, which doesn't show aliases.)
– dave_thompson_085
Jan 31 at 14:43
1
1
Where does
command
come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).– eewanco
Jan 29 at 22:38
Where does
command
come from? I don't have it in my installations (Red Hat 6.8 Enterprise and Cygwin64).– eewanco
Jan 29 at 22:38
1
1
@eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.
– Jeff Schaller
Jan 29 at 23:09
@eewanco, see unix.stackexchange.com/a/85250/117549; long story short, it's built in to bash, which is probably your shell.
– Jeff Schaller
Jan 29 at 23:09
3
3
command
is a POSIX Bourne shell builtin. It normally executes the command provided, but the -v
flag makes it behave more like type
, another shell builtin.– wyrm
Jan 30 at 1:29
command
is a POSIX Bourne shell builtin. It normally executes the command provided, but the -v
flag makes it behave more like type
, another shell builtin.– wyrm
Jan 30 at 1:29
@eewanco
type -a command
will show you. which
will only show executables on your $PATH
, not built-ins, keywords, functions or aliases.– l0b0
Jan 30 at 1:38
@eewanco
type -a command
will show you. which
will only show executables on your $PATH
, not built-ins, keywords, functions or aliases.– l0b0
Jan 30 at 1:38
@l0b0: on RedHat-family with bash and the default profile(s)
which
does find an applicable alias, because it aliases which
itself to run /usr/bin/which
and pipe it a list of the shell's aliases to look in (!) (Of course which
suppresses the alias and uses only the program, which doesn't show aliases.)– dave_thompson_085
Jan 31 at 14:43
@l0b0: on RedHat-family with bash and the default profile(s)
which
does find an applicable alias, because it aliases which
itself to run /usr/bin/which
and pipe it a list of the shell's aliases to look in (!) (Of course which
suppresses the alias and uses only the program, which doesn't show aliases.)– dave_thompson_085
Jan 31 at 14:43
add a comment |
You can test to see if figlet
exists
if type figlet >/dev/null 2>&1
then
echo Figlet is installed
fi
add a comment |
You can test to see if figlet
exists
if type figlet >/dev/null 2>&1
then
echo Figlet is installed
fi
add a comment |
You can test to see if figlet
exists
if type figlet >/dev/null 2>&1
then
echo Figlet is installed
fi
You can test to see if figlet
exists
if type figlet >/dev/null 2>&1
then
echo Figlet is installed
fi
answered Jan 29 at 19:16
roaimaroaima
44.8k755121
44.8k755121
add a comment |
add a comment |
A common way to do this is with test -x
aka [ -x
. Here is an example taken from /etc/init.d/ntp
on a Linux system:
if [ -x /usr/bin/lockfile-create ]; then
lockfile-create $LOCKFILE
lockfile-touch $LOCKFILE &
LOCKTOUCHPID="$!"
fi
This variant relies on knowing the full path of the executable. In /bin/lesspipe
I found an example which works around that by combining -x
and the which
command:
if [ -x "`which bunzip`" ]; then bunzip -c "$1"
else echo "No bunzip available"; fi ;;
That way this will work without knowing in advance where in the PATH
the bunzip
executable is.
4
Don't usewhich
. And even ifwhich
worked, usingtest -x
on its output is silly: if you get a path fromwhich
, it exists.
– Gilles
Jan 30 at 9:29
1
@Gilles: Technically speaking,test -x
does more than just check if a file exists (that's whattest -e
is for). It also checks if the file has the execute permissions set.
– comfreak
Feb 1 at 19:19
@comfreak So doeswhich
.
– Gilles
Feb 1 at 20:25
add a comment |
A common way to do this is with test -x
aka [ -x
. Here is an example taken from /etc/init.d/ntp
on a Linux system:
if [ -x /usr/bin/lockfile-create ]; then
lockfile-create $LOCKFILE
lockfile-touch $LOCKFILE &
LOCKTOUCHPID="$!"
fi
This variant relies on knowing the full path of the executable. In /bin/lesspipe
I found an example which works around that by combining -x
and the which
command:
if [ -x "`which bunzip`" ]; then bunzip -c "$1"
else echo "No bunzip available"; fi ;;
That way this will work without knowing in advance where in the PATH
the bunzip
executable is.
4
Don't usewhich
. And even ifwhich
worked, usingtest -x
on its output is silly: if you get a path fromwhich
, it exists.
– Gilles
Jan 30 at 9:29
1
@Gilles: Technically speaking,test -x
does more than just check if a file exists (that's whattest -e
is for). It also checks if the file has the execute permissions set.
– comfreak
Feb 1 at 19:19
@comfreak So doeswhich
.
– Gilles
Feb 1 at 20:25
add a comment |
A common way to do this is with test -x
aka [ -x
. Here is an example taken from /etc/init.d/ntp
on a Linux system:
if [ -x /usr/bin/lockfile-create ]; then
lockfile-create $LOCKFILE
lockfile-touch $LOCKFILE &
LOCKTOUCHPID="$!"
fi
This variant relies on knowing the full path of the executable. In /bin/lesspipe
I found an example which works around that by combining -x
and the which
command:
if [ -x "`which bunzip`" ]; then bunzip -c "$1"
else echo "No bunzip available"; fi ;;
That way this will work without knowing in advance where in the PATH
the bunzip
executable is.
A common way to do this is with test -x
aka [ -x
. Here is an example taken from /etc/init.d/ntp
on a Linux system:
if [ -x /usr/bin/lockfile-create ]; then
lockfile-create $LOCKFILE
lockfile-touch $LOCKFILE &
LOCKTOUCHPID="$!"
fi
This variant relies on knowing the full path of the executable. In /bin/lesspipe
I found an example which works around that by combining -x
and the which
command:
if [ -x "`which bunzip`" ]; then bunzip -c "$1"
else echo "No bunzip available"; fi ;;
That way this will work without knowing in advance where in the PATH
the bunzip
executable is.
edited Jan 30 at 10:08
Greg A. Woods
50237
50237
answered Jan 29 at 21:28
kasperdkasperd
2,45011127
2,45011127
4
Don't usewhich
. And even ifwhich
worked, usingtest -x
on its output is silly: if you get a path fromwhich
, it exists.
– Gilles
Jan 30 at 9:29
1
@Gilles: Technically speaking,test -x
does more than just check if a file exists (that's whattest -e
is for). It also checks if the file has the execute permissions set.
– comfreak
Feb 1 at 19:19
@comfreak So doeswhich
.
– Gilles
Feb 1 at 20:25
add a comment |
4
Don't usewhich
. And even ifwhich
worked, usingtest -x
on its output is silly: if you get a path fromwhich
, it exists.
– Gilles
Jan 30 at 9:29
1
@Gilles: Technically speaking,test -x
does more than just check if a file exists (that's whattest -e
is for). It also checks if the file has the execute permissions set.
– comfreak
Feb 1 at 19:19
@comfreak So doeswhich
.
– Gilles
Feb 1 at 20:25
4
4
Don't use
which
. And even if which
worked, using test -x
on its output is silly: if you get a path from which
, it exists.– Gilles
Jan 30 at 9:29
Don't use
which
. And even if which
worked, using test -x
on its output is silly: if you get a path from which
, it exists.– Gilles
Jan 30 at 9:29
1
1
@Gilles: Technically speaking,
test -x
does more than just check if a file exists (that's what test -e
is for). It also checks if the file has the execute permissions set.– comfreak
Feb 1 at 19:19
@Gilles: Technically speaking,
test -x
does more than just check if a file exists (that's what test -e
is for). It also checks if the file has the execute permissions set.– comfreak
Feb 1 at 19:19
@comfreak So does
which
.– Gilles
Feb 1 at 20:25
@comfreak So does
which
.– Gilles
Feb 1 at 20:25
add a comment |
At the start of your script, check if figlet
exists, and if it does not, define a shell function that does nothing:
type figlet >/dev/null 2>&1 || figlet() :;
type
checks if figlet
exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1
discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :;
defines figlet
as a function that does nothing.
This way you don't have to edit every line of your script that uses figlet
, or check if it exists every time figlet
is called.
You can add a diagnostic message, if you like:
type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ;
As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.
I like the simplicity of this answer. You could also replacetype figlet >/dev/null 2>&1
withhash figlet 2>/dev/null
if you're using bash. (The OP said "if it's in my PATH".)
– Joe
Feb 1 at 21:44
add a comment |
At the start of your script, check if figlet
exists, and if it does not, define a shell function that does nothing:
type figlet >/dev/null 2>&1 || figlet() :;
type
checks if figlet
exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1
discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :;
defines figlet
as a function that does nothing.
This way you don't have to edit every line of your script that uses figlet
, or check if it exists every time figlet
is called.
You can add a diagnostic message, if you like:
type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ;
As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.
I like the simplicity of this answer. You could also replacetype figlet >/dev/null 2>&1
withhash figlet 2>/dev/null
if you're using bash. (The OP said "if it's in my PATH".)
– Joe
Feb 1 at 21:44
add a comment |
At the start of your script, check if figlet
exists, and if it does not, define a shell function that does nothing:
type figlet >/dev/null 2>&1 || figlet() :;
type
checks if figlet
exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1
discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :;
defines figlet
as a function that does nothing.
This way you don't have to edit every line of your script that uses figlet
, or check if it exists every time figlet
is called.
You can add a diagnostic message, if you like:
type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ;
As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.
At the start of your script, check if figlet
exists, and if it does not, define a shell function that does nothing:
type figlet >/dev/null 2>&1 || figlet() :;
type
checks if figlet
exists as a shell built-in, function, alias, or keyword, >/dev/null 2>&1
discards stdin and stdout so you don't get any output, and if it does not exist, figlet() :;
defines figlet
as a function that does nothing.
This way you don't have to edit every line of your script that uses figlet
, or check if it exists every time figlet
is called.
You can add a diagnostic message, if you like:
type figlet >/dev/null 2>&1 || echo 'figlet not installed.' ; figlet() :; ;
As a bonus, since you didn't mention which shell you are using, I believe this is POSIX compliant, so it should work on most any shell.
edited Jan 30 at 11:17
answered Jan 30 at 11:04
ChrisChris
1,120515
1,120515
I like the simplicity of this answer. You could also replacetype figlet >/dev/null 2>&1
withhash figlet 2>/dev/null
if you're using bash. (The OP said "if it's in my PATH".)
– Joe
Feb 1 at 21:44
add a comment |
I like the simplicity of this answer. You could also replacetype figlet >/dev/null 2>&1
withhash figlet 2>/dev/null
if you're using bash. (The OP said "if it's in my PATH".)
– Joe
Feb 1 at 21:44
I like the simplicity of this answer. You could also replace
type figlet >/dev/null 2>&1
with hash figlet 2>/dev/null
if you're using bash. (The OP said "if it's in my PATH".)– Joe
Feb 1 at 21:44
I like the simplicity of this answer. You could also replace
type figlet >/dev/null 2>&1
with hash figlet 2>/dev/null
if you're using bash. (The OP said "if it's in my PATH".)– Joe
Feb 1 at 21:44
add a comment |
Another alternative -- a pattern I've seen in project auto configure scripts:
if [ -x /usr/bin/figlet ]
then
FIGLET=/usr/bin/figlet
else
FIGLET=:
fi
$FIGLET "Hello, world!"
In your specific case you could even do,
if [ -x /usr/bin/figlet ]
then
SAY=/usr/bin/figlet
elif [ -x /usr/local/bin/figlet ]
then
SAY=/usr/local/bin/figlet
elif [ -x /usr/bin/banner ]
then
SAY=/usr/bin/banner
else
SAY=/usr/bin/echo
fi
$SAY "Hello, world!"
If you don't know the specific path, you can try multiple elif
(see above) to try known locations, or just use the PATH
to always resolve the command:
if command -v figlet >/dev/null
then
SAY=figlet
elif command -v banner >/dev/null
then
SAY=banner
else
SAY=echo
fi
In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH
, perhaps in their own ~/bin
.
If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin
that might or might not be the command I expected.
3
What iffiglet
was in/usr/local/bin
or/home/bob/stuff/programs/executable/figlet
?
– Gilles
Jan 30 at 9:30
add a comment |
Another alternative -- a pattern I've seen in project auto configure scripts:
if [ -x /usr/bin/figlet ]
then
FIGLET=/usr/bin/figlet
else
FIGLET=:
fi
$FIGLET "Hello, world!"
In your specific case you could even do,
if [ -x /usr/bin/figlet ]
then
SAY=/usr/bin/figlet
elif [ -x /usr/local/bin/figlet ]
then
SAY=/usr/local/bin/figlet
elif [ -x /usr/bin/banner ]
then
SAY=/usr/bin/banner
else
SAY=/usr/bin/echo
fi
$SAY "Hello, world!"
If you don't know the specific path, you can try multiple elif
(see above) to try known locations, or just use the PATH
to always resolve the command:
if command -v figlet >/dev/null
then
SAY=figlet
elif command -v banner >/dev/null
then
SAY=banner
else
SAY=echo
fi
In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH
, perhaps in their own ~/bin
.
If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin
that might or might not be the command I expected.
3
What iffiglet
was in/usr/local/bin
or/home/bob/stuff/programs/executable/figlet
?
– Gilles
Jan 30 at 9:30
add a comment |
Another alternative -- a pattern I've seen in project auto configure scripts:
if [ -x /usr/bin/figlet ]
then
FIGLET=/usr/bin/figlet
else
FIGLET=:
fi
$FIGLET "Hello, world!"
In your specific case you could even do,
if [ -x /usr/bin/figlet ]
then
SAY=/usr/bin/figlet
elif [ -x /usr/local/bin/figlet ]
then
SAY=/usr/local/bin/figlet
elif [ -x /usr/bin/banner ]
then
SAY=/usr/bin/banner
else
SAY=/usr/bin/echo
fi
$SAY "Hello, world!"
If you don't know the specific path, you can try multiple elif
(see above) to try known locations, or just use the PATH
to always resolve the command:
if command -v figlet >/dev/null
then
SAY=figlet
elif command -v banner >/dev/null
then
SAY=banner
else
SAY=echo
fi
In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH
, perhaps in their own ~/bin
.
If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin
that might or might not be the command I expected.
Another alternative -- a pattern I've seen in project auto configure scripts:
if [ -x /usr/bin/figlet ]
then
FIGLET=/usr/bin/figlet
else
FIGLET=:
fi
$FIGLET "Hello, world!"
In your specific case you could even do,
if [ -x /usr/bin/figlet ]
then
SAY=/usr/bin/figlet
elif [ -x /usr/local/bin/figlet ]
then
SAY=/usr/local/bin/figlet
elif [ -x /usr/bin/banner ]
then
SAY=/usr/bin/banner
else
SAY=/usr/bin/echo
fi
$SAY "Hello, world!"
If you don't know the specific path, you can try multiple elif
(see above) to try known locations, or just use the PATH
to always resolve the command:
if command -v figlet >/dev/null
then
SAY=figlet
elif command -v banner >/dev/null
then
SAY=banner
else
SAY=echo
fi
In general, when writing scripts, I prefer to only call commands in specific locations specified by me. I don't like the uncertainty/risk of what the end user might have put into their PATH
, perhaps in their own ~/bin
.
If, for example, I was writing a complicated script for others that might remove files based on the output of a particular command I'm calling, I wouldn't want to accidentally pick up something in their ~/bin
that might or might not be the command I expected.
edited Feb 11 at 17:49
answered Jan 29 at 21:52
rrauenzarrauenza
42926
42926
3
What iffiglet
was in/usr/local/bin
or/home/bob/stuff/programs/executable/figlet
?
– Gilles
Jan 30 at 9:30
add a comment |
3
What iffiglet
was in/usr/local/bin
or/home/bob/stuff/programs/executable/figlet
?
– Gilles
Jan 30 at 9:30
3
3
What if
figlet
was in /usr/local/bin
or /home/bob/stuff/programs/executable/figlet
?– Gilles
Jan 30 at 9:30
What if
figlet
was in /usr/local/bin
or /home/bob/stuff/programs/executable/figlet
?– Gilles
Jan 30 at 9:30
add a comment |
type -p figlet > /dev/null && figlet "foo"
The bash type
command finds a command, function, alias, keyword, or builtin (see help type
) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet
in the path (-p
means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null
does), and if it returns true (&&
), it will execute figlet
.
This is simpler if figlet
is in a fixed location:
[ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"
Here we're using the test
command (a.k.a. [
) to see if /usr/bin/figlet
is executable (-x
) and if so (&&
) execute it. This solution I think is more portable than using type
which is a bashism I believe.
You could make a function that does this for you:
function x()
if type -p "$1" >/dev/null; then
cmd="$1"
shift
"$cmd" "$@"
fi
(The quotes are necessary owing to potential spaces)
Then you'd just do:
x figlet "foo"
add a comment |
type -p figlet > /dev/null && figlet "foo"
The bash type
command finds a command, function, alias, keyword, or builtin (see help type
) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet
in the path (-p
means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null
does), and if it returns true (&&
), it will execute figlet
.
This is simpler if figlet
is in a fixed location:
[ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"
Here we're using the test
command (a.k.a. [
) to see if /usr/bin/figlet
is executable (-x
) and if so (&&
) execute it. This solution I think is more portable than using type
which is a bashism I believe.
You could make a function that does this for you:
function x()
if type -p "$1" >/dev/null; then
cmd="$1"
shift
"$cmd" "$@"
fi
(The quotes are necessary owing to potential spaces)
Then you'd just do:
x figlet "foo"
add a comment |
type -p figlet > /dev/null && figlet "foo"
The bash type
command finds a command, function, alias, keyword, or builtin (see help type
) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet
in the path (-p
means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null
does), and if it returns true (&&
), it will execute figlet
.
This is simpler if figlet
is in a fixed location:
[ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"
Here we're using the test
command (a.k.a. [
) to see if /usr/bin/figlet
is executable (-x
) and if so (&&
) execute it. This solution I think is more portable than using type
which is a bashism I believe.
You could make a function that does this for you:
function x()
if type -p "$1" >/dev/null; then
cmd="$1"
shift
"$cmd" "$@"
fi
(The quotes are necessary owing to potential spaces)
Then you'd just do:
x figlet "foo"
type -p figlet > /dev/null && figlet "foo"
The bash type
command finds a command, function, alias, keyword, or builtin (see help type
) and prints out the location or definition. It also returns a return code representing the result of the search; true (0) if found. So what we're doing here is trying to find figlet
in the path (-p
means only look for files, not built-ins or functions, and also suppresses error messages), discarding output (that's what > /dev/null
does), and if it returns true (&&
), it will execute figlet
.
This is simpler if figlet
is in a fixed location:
[ -x /usr/bin/figlet ] && /usr/bin/figlet "foo"
Here we're using the test
command (a.k.a. [
) to see if /usr/bin/figlet
is executable (-x
) and if so (&&
) execute it. This solution I think is more portable than using type
which is a bashism I believe.
You could make a function that does this for you:
function x()
if type -p "$1" >/dev/null; then
cmd="$1"
shift
"$cmd" "$@"
fi
(The quotes are necessary owing to potential spaces)
Then you'd just do:
x figlet "foo"
edited Jan 29 at 22:26
answered Jan 29 at 21:56
eewancoeewanco
295212
295212
add a comment |
add a comment |
o/,
I would say something like
#!/usr/bin/env bash
# if figlet is installed :
if [ "$(which figlet 2>/dev/null)" ]; then
# do what you wanted to do
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
# if not
else
# exit program with an error
echo "please install figlet"
exit 1
fi
add a comment |
o/,
I would say something like
#!/usr/bin/env bash
# if figlet is installed :
if [ "$(which figlet 2>/dev/null)" ]; then
# do what you wanted to do
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
# if not
else
# exit program with an error
echo "please install figlet"
exit 1
fi
add a comment |
o/,
I would say something like
#!/usr/bin/env bash
# if figlet is installed :
if [ "$(which figlet 2>/dev/null)" ]; then
# do what you wanted to do
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
# if not
else
# exit program with an error
echo "please install figlet"
exit 1
fi
o/,
I would say something like
#!/usr/bin/env bash
# if figlet is installed :
if [ "$(which figlet 2>/dev/null)" ]; then
# do what you wanted to do
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
# if not
else
# exit program with an error
echo "please install figlet"
exit 1
fi
answered Jan 30 at 9:49
Jus de PatateJus de Patate
111
111
add a comment |
add a comment |
You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.
if figlet --help >/dev/null 2>&1 ; then
# figlet is available
echo "foo"
figlet "starting"
#etc
else
rc=$?
echo "figlet is not installed or not working correctly (return code $rc)"
fi
Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do
figlet --help >/dev/null 2>&1
rc=$?
if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
echo "command figlet not found"
else
figlet "whatever" # use figlet
fi
The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.
– Chris
Jan 31 at 11:15
If you really want to test only for its installation, then you want to test if$?
equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, ifcommand --help
fails, then the installation is borked sufficiently that it might as well not be there!.
– nigel222
Jan 31 at 12:06
1
126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on--help
being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it.at --help
fails withat: invalid option -- '-'
, for instance, and an exit status of130
on my system.
– Chris
Jan 31 at 12:47
Also, of course, if figlet can exit with status 127 that could be a problem too.
– Chris
Jan 31 at 15:14
Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as-?
--help
--version
... or you could find out whatfiglet -0 --illegal
exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).
– nigel222
Jan 31 at 15:29
add a comment |
You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.
if figlet --help >/dev/null 2>&1 ; then
# figlet is available
echo "foo"
figlet "starting"
#etc
else
rc=$?
echo "figlet is not installed or not working correctly (return code $rc)"
fi
Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do
figlet --help >/dev/null 2>&1
rc=$?
if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
echo "command figlet not found"
else
figlet "whatever" # use figlet
fi
The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.
– Chris
Jan 31 at 11:15
If you really want to test only for its installation, then you want to test if$?
equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, ifcommand --help
fails, then the installation is borked sufficiently that it might as well not be there!.
– nigel222
Jan 31 at 12:06
1
126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on--help
being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it.at --help
fails withat: invalid option -- '-'
, for instance, and an exit status of130
on my system.
– Chris
Jan 31 at 12:47
Also, of course, if figlet can exit with status 127 that could be a problem too.
– Chris
Jan 31 at 15:14
Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as-?
--help
--version
... or you could find out whatfiglet -0 --illegal
exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).
– nigel222
Jan 31 at 15:29
add a comment |
You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.
if figlet --help >/dev/null 2>&1 ; then
# figlet is available
echo "foo"
figlet "starting"
#etc
else
rc=$?
echo "figlet is not installed or not working correctly (return code $rc)"
fi
Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do
figlet --help >/dev/null 2>&1
rc=$?
if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
echo "command figlet not found"
else
figlet "whatever" # use figlet
fi
You can do a test execution, suppressing any output, and test success/failure code. Choose arguments to figlet to make this test inexpensive. -? or --help or --version are obvious possibilities.
if figlet --help >/dev/null 2>&1 ; then
# figlet is available
echo "foo"
figlet "starting"
#etc
else
rc=$?
echo "figlet is not installed or not working correctly (return code $rc)"
fi
Added in response to comment below: if you really want to test that figlet exists, not that it's usable, then you would do
figlet --help >/dev/null 2>&1
rc=$?
if [ $rc -eq 127 ] ; then # 127 is "command not found" on linux bash 4.4.23(1)
echo "command figlet not found"
else
figlet "whatever" # use figlet
fi
edited Jan 31 at 12:10
answered Jan 31 at 10:50
nigel222nigel222
1514
1514
The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.
– Chris
Jan 31 at 11:15
If you really want to test only for its installation, then you want to test if$?
equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, ifcommand --help
fails, then the installation is borked sufficiently that it might as well not be there!.
– nigel222
Jan 31 at 12:06
1
126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on--help
being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it.at --help
fails withat: invalid option -- '-'
, for instance, and an exit status of130
on my system.
– Chris
Jan 31 at 12:47
Also, of course, if figlet can exit with status 127 that could be a problem too.
– Chris
Jan 31 at 15:14
Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as-?
--help
--version
... or you could find out whatfiglet -0 --illegal
exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).
– nigel222
Jan 31 at 15:29
add a comment |
The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.
– Chris
Jan 31 at 11:15
If you really want to test only for its installation, then you want to test if$?
equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, ifcommand --help
fails, then the installation is borked sufficiently that it might as well not be there!.
– nigel222
Jan 31 at 12:06
1
126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on--help
being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it.at --help
fails withat: invalid option -- '-'
, for instance, and an exit status of130
on my system.
– Chris
Jan 31 at 12:47
Also, of course, if figlet can exit with status 127 that could be a problem too.
– Chris
Jan 31 at 15:14
Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as-?
--help
--version
... or you could find out whatfiglet -0 --illegal
exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).
– nigel222
Jan 31 at 15:29
The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.
– Chris
Jan 31 at 11:15
The problem here is that figlet can fail for reasons besides not being installed, so just testing the exit code doesn't suffice.
– Chris
Jan 31 at 11:15
If you really want to test only for its installation, then you want to test if
$?
equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, if command --help
fails, then the installation is borked sufficiently that it might as well not be there!.– nigel222
Jan 31 at 12:06
If you really want to test only for its installation, then you want to test if
$?
equals 127 (on my linux system). 127 is "command not found". But my thinking is that for rational commands, if command --help
fails, then the installation is borked sufficiently that it might as well not be there!.– nigel222
Jan 31 at 12:06
1
1
126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on
--help
being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it. at --help
fails with at: invalid option -- '-'
, for instance, and an exit status of 130
on my system.– Chris
Jan 31 at 12:47
126 is "command found but not executable," so you would want to test against that as well. Unfortunately, you can't depend on
--help
being available. Posix utilities don't have it, for one, and posix guidelines actually recommend against it. at --help
fails with at: invalid option -- '-'
, for instance, and an exit status of 130
on my system.– Chris
Jan 31 at 12:47
Also, of course, if figlet can exit with status 127 that could be a problem too.
– Chris
Jan 31 at 15:14
Also, of course, if figlet can exit with status 127 that could be a problem too.
– Chris
Jan 31 at 15:14
Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as
-?
--help
--version
... or you could find out what figlet -0 --illegal
exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).– nigel222
Jan 31 at 15:29
Fair point about 126. Most sane utilities have some sort of lightweight harmless command options, such as
-?
--help
--version
... or you could find out what figlet -0 --illegal
exits with, and treat that as your success indicator (as long as it's not 127, which I would class as sabotage).– nigel222
Jan 31 at 15:29
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f497526%2flinux-shell-script-run-a-program-only-if-it-exists-ignore-it-if-it-does-not-ex%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
stackoverflow.com/questions/592620/…
– gip
Jan 29 at 19:22
@sudodus : just ignoring the 'figlet' (and its parameters) command would be OK. Continuing execution, of course.
– Sopalajo de Arrierez
Jan 30 at 10:50
2
The title to this question got me in all sorts of metaphysical problems
– g_uint
Jan 30 at 12:31
2
Do you want to ignore all errors? Just use
figlet ... || true
.– Giacomo Alzetta
Jan 30 at 13:40
If you don’t care about exit codes a shortcut is to use
figlet || true
, but in your case probably a shell function which Echos plaintext If no Banner can be printed is more likely what you want.– eckes
Jan 31 at 1:26