detecting command not found in bash script
If this should be done from a script, it's natural to use a conditional to express this kind of behaviour:
asdf 2> /dev/null || exit 1
How to handle command not found in bash
Insert this before your first echo
line if you use bash >= 4.0:
command_not_found_handle() { echo "not found"; return 127; }
And then insert this after your last echo
line to get rid of this function:
unset command_not_found_handle
Output, e.g.:
...RVM Version : not found
...Node Version : v4.2.6
...Ruby Version : ruby 2.3.1p112 (2016-04-26) [x86_64-linux-gnu]
...Bundler Version : not found
...Passenger Version: not found
Unix Bash Script - command not found
The syntax is correct, but it throws that error.
No, the syntax is not correct. With $(du -sh $varDirectory) -gt "$minimumsize"
you are running the command du -sh $varDirectory
, then you take its output and run the output as a command again. In your case, the output started with 299M
so bash complained that it could not find the 299M
-command.
You probably wanted to write
if [ -d "$varDirectory" ] &&
[ $(du -s "$varDirectory" | cut -f1) -gt "$minimumsize" ]
then
echo "greater than $minimumsize"
else
echo "less than or equal $minimumsize or not a directory"
fi
Note that you can compare only numbers. However, the output of du -sh
is not a number, it is something like 299m directory
. Disable human readable format to remove the k
, m
, g
, ... suffixes, then use cut -f1
to extract only the number.
Also you don't need a loop. while
repeats. if
runs only once. With if
you can also use an else
branch.
command not found when running shell script
Maybe there is a (invisible) character there that should not be there. Try typing it again from scratch in the environment that it will run (ex: Linux) or use this command od -c /folder/script.sh
to reveal those pesky characters.
How can I check if a program exists from a Bash script?
Answer
POSIX compatible:
command -v <the_command>
Example use:
if ! command -v <the_command> &> /dev/null
then
echo "<the_command> could not be found"
exit
fi
For Bash specific environments:
hash <the_command> # For regular commands. Or...
type <the_command> # To check built-ins and keywords
Explanation
Avoid which
. Not only is it an external process you're launching for doing very little (meaning builtins like hash
, type
or command
are way cheaper), you can also rely on the builtins to actually do what you want, while the effects of external commands can easily vary from system to system.
Why care?
- Many operating systems have a
which
that doesn't even set an exit status, meaning theif which foo
won't even work there and will always report thatfoo
exists, even if it doesn't (note that some POSIX shells appear to do this forhash
too). - Many operating systems make
which
do custom and evil stuff like change the output or even hook into the package manager.
So, don't use which
. Instead use one of these:
command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed. Aborting."; exit 1; }
(Minor side-note: some will suggest 2>&-
is the same 2>/dev/null
but shorter – this is untrue. 2>&-
closes FD 2 which causes an error in the program when it tries to write to stderr, which is very different from successfully writing to it and discarding the output (and dangerous!))
If your hash bang is /bin/sh
then you should care about what POSIX says. type
and hash
's exit codes aren't terribly well defined by POSIX, and hash
is seen to exit successfully when the command doesn't exist (haven't seen this with type
yet). command
's exit status is well defined by POSIX, so that one is probably the safest to use.
If your script uses bash
though, POSIX rules don't really matter anymore and both type
and hash
become perfectly safe to use. type
now has a -P
to search just the PATH
and hash
has the side-effect that the command's location will be hashed (for faster lookup next time you use it), which is usually a good thing since you probably check for its existence in order to actually use it.
As a simple example, here's a function that runs gdate
if it exists, otherwise date
:
gnudate() {
if hash gdate 2>/dev/null; then
gdate "$@"
else
date "$@"
fi
}
Alternative with a complete feature set
You can use scripts-common to reach your need.
To check if something is installed, you can do:
checkBin <the_command> || errorMessage "This tool requires <the_command>. Install it please, and then run this tool again."
when command not found, bash `$?` return 0, not 127
I read the answer of @chepner in detecting command not found in bash script
and add the unset command_not_found_handle
at the first line has solved the matter
BASH script, !=: command not found
That's not the way to compare it.
if $OUTP != average:
Should be
if [[ $OUTP != average: ]]
Some line seemed odd as well
OUTP= uptime | awk '{print $10}' | cut -f1 -d,
I think should be
OUTP=$(uptime | awk '{print $10}' | cut -f1 -d,)
And
then $OUTP >> $Oad.lst
if you want to send the value of the variable to the file, it should be
then echo "$OUTP" >> "$Oad.lst"
Overall I would suggest a format like this:
#!/bin/bash
Oad=$(date +%Y_%m_%d.%H.%M.%S)
for i in {1..120}; do
OUTP=$(uptime | awk '{print $10}' | cut -f1 -d,)
echo "$OUTP"
if [[ $OUTP != average: ]]; then
echo "$OUTP" >> "$Oad.lst"
sleep 60
fi
done
awk '{if(min==""){min=max=$1}; if($1>max) {max=$1}; if($1<min) {min=$1}; total+=$1; count+=1} END {print total/count, max, min}' "$Oad.lst" > "$Oad.out"
One more note. For:
if [[ $OUTP != average: ]]; then
You probably mean it as:
if [[ $OUTP != *average:* ]]; then
To match any line not containing average:
instead of any line that's not exactly like it.
Related Topics
How to Get the Exit Status a Loop in Bash
Can Inode and Crtime Be Used as a Unique File Identifier
Deceive the Jvm About the Number of Available Cores (On Linux)
Solution for Git Gui Client for Remote Ssh
What Does -Prune Option in Find Do
How to Give Highest Priority to Ethernet Interrupt in Linux
How to Find Out What Linux Capabilities a Process Requires to Work
Is There a Core Linux API Analogous to Windows Winapi, in Particular for Creating Gui Applications
How to Remove Only the First Occurrence of a Line in a File Using Sed
How to Determine the Process Memory Limit in Linux
How to Print a String to the Terminal in X86-64 Assembly (Nasm) Without Syscall
Does Linux Time Division Processes or Threads
Linux Keyboard Event Capturing /Dev/Inputx
Does Madvise(_, _, Madv_Dontneed) Instruct the Os to Lazily Write to Disk