In a (ba)sh script, how do I ignore file-not-found errors?
I am writing a script that reads a (partial) filename from stdin, using:
read file; $FILEDIR/$file.sh
I need to give the script functionality to reject filenames that don't exist.
e.g.
$UTILDIR does NOT contains script.sh
User types script
Script tries to access $UTILDIR/script.sh and fails as
./run.sh: line 32: /utiltest/script.sh: No such file or directory
How do I make the script print an error, but continue the script without printing the 'normal' error?
You can test whether the file exists using the code in #gogaman's answer, but you are probably more interested in knowing whether the file is present and executable. For that, you should use the -x test instead of -e
if [ -x "$FILEDIR/$file.sh" ]; then
echo file exists
else
echo file does not exist or is not executable
fi
if [ -e $FILEDIR/$file.sh ]; then
echo file exists;
else
echo file does not exist;
fi
Here we can define a shell procedure that runs only if the file exists
run-if-present () {
echo $1 is really there
}
[ -e $thefile ] && run-if-present $thefile
Depending on what you do with the script, the command will fail with a specific exit code. If you are executing the script, the exit code can be 126 (permission denied) or 127 (file not found).
command
if (($? == 126 || $? == 127))
then
echo 'Command not found or not executable' > /dev/stderr
fi
Related
The goal is to check the existence of a file and create a blank file if this doesn't exist, using Shell Script on the Pre-session-command (Informatica PowerCenter) like the code below:
ParamDirTrabalho=/dir/powercenter/project1
ParamArq=file.csv
ParamQtdArq=`cat ${ParamDirTrabalho}/${ParamArq} | wc -l`
if [ $ParamQtdArq == 0 ];then touch ${ParamDirTrabalho}/${ParamArq};fi
This is the error:
Message: [Pre/Post Session Command] Process id 10683. Standard output and error:
sh: line 2:
: command not found
cat: /dir/powercenter/project1
/file.csv
: No such file or directory
sh: line 4:
: command not found
I can execute successfully when pointing to a sh file with the code above. But I need to write the code inside the pre-session-command.
Please enclose parameters by double quotes.
ParamDirTrabalho="/dir/powercenter/project1"
ParamArq="file.csv"
Also pls make sure you provide RWX permission to folders.
You cannot get the WC from a file if it doesn't exist at all. That's what the error is "No such file or directory" if I understand it right. What you need to do is check if file exists or not rather than the count and then touch if it doesn't exist.
if [ ! -f filename ];then touch filename; fi
or
if [ -f filename ];then exit 0; else touch filename; fi
I currently have a directory that is supposed to have 500 files. Each file is of the name form List.1.rds, ... List.500.rds. The way I can see which ones are missing is by the following code in bash:
for((i=1; i<=500; i++)); do name="List.${i}.rds"; [[ ! -e "$name" ]] && echo "missing $name"; done
If a file is missing, it returns the missing file name. However, I would like to go one step further and stop the entire script should any file be missing. Is there a way to do this? thanks.
It can be as simple as setting a flag when a file is missing:
miss=0
for ((i=1;i<=500;i++)); do
file=List.$i.rds
if [[ ! -e $file ]]; then
echo "Missing $file"
miss=1
fi
done
# exit if "miss" flag is 1
((miss)) && exit 1
I want to check if a file or directory with same name exists.
Is there any operator (expect -e) to check the file or directory, I dont want to add any extra condition.
Following code works fine to check the existence of a file:
#!/bin/bash
if [ -e /path/to/the/file/sample ]
then
echo "ok"
else
echo "nok"
fi
Note that sample can be a file or a directory.
In my tests with bash 4.2 , the condition [ -e /path/to/the/file/sample ] works for BOTH files and directories.
As an alternative you can :
Either to use another operator like -d according to bash man page.
if [ -e /path/to/the/file/sample ] || [ -d /path/to/the/file/sample ];then echo "ok"; else echo "nok";fi
Or to use the exit code of a command like ls.
if ls "/path/to/the/file/sample" &>/dev/null ; then echo "is here";else echo "not here";fi
If you try to perform ls on an existed file or directory ls will return 0, otherwise will return a non-zero value (returns 2 in my tests for non-existed files or directories).
Quoting is necessary to handle correct names that may include spaces.
I have written a small bash program which needs to read a file with name input. I want the script to print the message file not found and exit or kill itself if it can't find the file.
Just before reading, check if the file exists:
if [ ! -f input ]; then
echo "File Not found"
exit 1
fi
Use the Bash Exit Handler
You can use Bash's set -e option to handle most similar situations automatically, with system-generated (but generally sensible) error messages. For example:
$ set -e; ls /tmp/doesnt_exist
ls: cannot access /tmp/doesnt_exist: No such file or directory
Note that the -e option will also cause the current shell to exit immediately with a non-zero exit status after displaying the error message. This is a quick-and-dirty way to get what you want.
Manually Test for a Readable File
If you really need a custom message, then you want to use a test conditional. For example, to ensure that a file exists and is readable you could use something similar to the following:
if [[ -r "/path/to/input" ]]; then
: # do something with "input"
else
# Send message to standard error.
echo "file not found" > /dev/stderr
# Exit with EX_DATAERR from sysexits.h.
exit 65
fi
See Also
See man 1 test for a more complete list of possible test conditionals.
I am attempting to write a bash script that changes directory and then runs an existing script in the new working directory.
This is what I have so far:
#!/bin/bash
cd /path/to/a/folder
./scriptname
scriptname is an executable file that exists in /path/to/a/folder - and (needless to say), I do have permission to run that script.
However, when I run this mind numbingly simple script (above), I get the response:
scriptname: No such file or directory
What am I missing?! the commands work as expected when entered at the CLI, so I am at a loss to explain the error message. How do I fix this?
Looking at your script makes me think that the script you want to launch a script which is locate in the initial directory. Since you change you directory before executing it won't work.
I suggest the following modified script:
#!/bin/bash
SCRIPT_DIR=$PWD
cd /path/to/a/folder
$SCRIPT_DIR/scriptname
cd /path/to/a/folder
pwd
ls
./scriptname
which'll show you what it thinks it's doing.
I usually have something like this in my useful script directory:
#!/bin/bash
# Provide usage information if not arguments were supplied
if [[ "$#" -le 0 ]]; then
echo "Usage: $0 <executable> [<argument>...]" >&2
exit 1
fi
# Get the executable by removing the last slash and anything before it
X="${1##*/}"
# Get the directory by removing the executable name
D="${1%$X}"
# Check if the directory exists
if [[ -d "$D" ]]; then
# If it does, cd into it
cd "$D"
else
if [[ "$D" ]]; then
# Complain if a directory was specified, but does not exist
echo "Directory '$D' does not exist" >&2
exit 1
fi
fi
# Check if the executable is, well, executable
if [[ -x "$X" ]]; then
# Run the executable in its directory with the supplied arguments
exec ./"$X" "${#:2}"
else
# Complain if the executable is not a valid
echo "Executable '$X' does not exist in '$D'" >&2
exit 1
fi
Usage:
$ cdexec
Usage: /home/archon/bin/cdexec <executable> [<argument>...]
$ cdexec /bin/ls ls
ls
$ cdexec /bin/xxx/ls ls
Directory '/bin/xxx/' does not exist
$ cdexec /ls ls
Executable 'ls' does not exist in '/'
One source of such error messages under those conditions is a broken symlink.
However, you say the script works when run from the command line. I would also check to see whether the directory is a symlink that's doing something other than what you expect.
Does it work if you call it in your script with the full path instead of using cd?
#!/bin/bash
/path/to/a/folder/scriptname
What about when called that way from the command line?