How can I suppress error messages for a shell command?
For example, if there are only jpg files in a directory, running ls *.zip gives an error message:
$ ls *.zip
ls: cannot access '*.zip': No such file or directory
Is there an option to suppress such error messages? I want to use this command in a Bash script, but I want to hide all errors.
Most Unix commands, including ls, will write regular output to standard output and error messages to standard error, so you can use Bash redirection to throw away the error messages while leaving the regular output in place:
ls *.zip 2> /dev/null
$ ls *.zip 2>/dev/null
will redirect any error messages on stderr to /dev/null (i.e. you won't see them)
Note the return value (given by $?) will still reflect that an error occurred.
To suppress error messages and also return the exit status zero, append || true. For example:
$ ls *.zip && echo hello
ls: cannot access *.zip: No such file or directory
$ ls *.zip 2>/dev/null && echo hello
$ ls *.zip 2>/dev/null || true && echo hello
hello
$ touch x.zip
$ ls *.zip 2>/dev/null || true && echo hello
x.zip
hello
I attempted ls -R [existing file] and got an immediate error.
ls: cannot access 'existing file': No such file or directory
So, I used the following:
ls -R 2>dev/null | grep -i [existing file]*
ls -R 2>dev/null | grep -i text*
Or, in your case:
ls -R 2>dev/null | grep -i *.zip
My solution with a raspberry pi3 with buster.
ls -R 2>/dev/null | grep -i [existing file]*
2>/dev/null is very usefull with Bash script to avoid useless warnings or errors.
Do not forget slash caracter
Related
How can I suppress error messages for a shell command?
For example, if there are only jpg files in a directory, running ls *.zip gives an error message:
$ ls *.zip
ls: cannot access '*.zip': No such file or directory
Is there an option to suppress such error messages? I want to use this command in a Bash script, but I want to hide all errors.
Most Unix commands, including ls, will write regular output to standard output and error messages to standard error, so you can use Bash redirection to throw away the error messages while leaving the regular output in place:
ls *.zip 2> /dev/null
$ ls *.zip 2>/dev/null
will redirect any error messages on stderr to /dev/null (i.e. you won't see them)
Note the return value (given by $?) will still reflect that an error occurred.
To suppress error messages and also return the exit status zero, append || true. For example:
$ ls *.zip && echo hello
ls: cannot access *.zip: No such file or directory
$ ls *.zip 2>/dev/null && echo hello
$ ls *.zip 2>/dev/null || true && echo hello
hello
$ touch x.zip
$ ls *.zip 2>/dev/null || true && echo hello
x.zip
hello
I attempted ls -R [existing file] and got an immediate error.
ls: cannot access 'existing file': No such file or directory
So, I used the following:
ls -R 2>dev/null | grep -i [existing file]*
ls -R 2>dev/null | grep -i text*
Or, in your case:
ls -R 2>dev/null | grep -i *.zip
My solution with a raspberry pi3 with buster.
ls -R 2>/dev/null | grep -i [existing file]*
2>/dev/null is very usefull with Bash script to avoid useless warnings or errors.
Do not forget slash caracter
I'm experimenting with some arguments for the rename command by using -n option to do "dry runs". How to make it output into a file so I can analyze more? The following does not work -- the resultant rename.log is empty:
bash$ echo "XXX" > \"XXX\"__XXX.txt
$ rename -n 's/"([^\/"《》]+)"__(.*)/“$1”__$2/' '{}' \; *.txt > rename.log
'"XXX"__XXX.txt' would be renamed to '“XXX”__XXX.txt'
Mark's comment is correct, it seems the -n option outputs on stderr. So you can run a command like this:
rename -n [options] > rename.log 2>&1
If you wanted to pipe the output to another command (as I was trying to do), put the redirection before the pipe:
rename -n [options] 2>&1 | less
I am running below commands in a script
move_jobs() {
cd $JOB_DIR
for i in `cat $JOBS_FILE`
do
if [ `ls | grep -i ^${i}- | wc -l` -gt 0 ]; then
cd $i
if [ ! -d jobs ]; then
mkdir jobs && cd .. && mv "${i}"-* "${i}"/jobs/
else
cd .. && mv "${i}"-* "${i}"/jobs/
fi
error_handler $?
fi
done
}
but it failing as
mv: cannot stat `folder-*': No such file or directory
Not sure why move command is failing with regular expression
Your script is overly complicated and has several issues, one of which will be the problem, I guess it's the ls | grep ... part, but to find that out, you should include some debug logging.
for i in $(cat ...) loops through words, not lines.
Do not parse ls
And if you still do, do not ever grep for filenames but include it in your ls call: ls "${i}"-* | wc -l.
You do not need to check if a folder exists when the only thing that is different then is that you create it. You can use mkdir -p instead.
Jumping around folders in your script makes it almost unreadable, as you need to keep track of all cd commands when reading your script.
You could simply write the following, which I think will do what you want:
xargs -a "$JOBS_FILE" -I{} \
sh -c "
mkdir -p '$JOB_DIR/{}/jobs';
mv '$JOB_DIR/{}-'* '$JOB_DIR/{}/jobs';
"
or if you need more control:
while IFS= read -r jid; do
if ls "$JOB_DIR/$jid-"* &>/dev/null; then
TARGET_DIR="$JOB_DIR/$jid/jobs"
mkdir -p "$TARGET_DIR"
mv "$JOB_DIR/$jid-"* "$TARGET_DIR"
echo "OK"
else
echo "No files to move."
fi
done < "$JOBS_FILE"
I am trying to assign the output of mkdir command to a variable. So I can use the directory further.
-bash-4.1$ pwd
/user/ravi/myscripts/tmpdata
-bash-4.1$ OUTPUT=$(mkdir tmpbkp.`date +%F`)
-bash-4.1$ ls | grep tmp
tmpbkp.2017-04-06
-bash-4.1$ echo "$OUTPUT"
But the directory name is not assigning to the variable. Could you please correct me where I am wrong.
When you run the mkdir command by itself, look how much output it produces:
$ mkdir foo
$
None!
When you use a command substitution to generate the argument to mkdir, look how much extra output you get:
$ mkdir tmpbkp.`date +%F`
$
None!
When you put it inside $() it still produces no output.
There is a -v option for mkdir (in the GNU version at least) which produces some output, but it's probably not what you want.
You want the name of the directory in a variable? Put it in a variable first, then call mkdir.
$ thedir=tmpbkp.`date +%F`
$ mkdir $thedir
$ echo $thedir
tmpbkp.2017-04-06
$
I'm trying to echo the new directory that I'm creating in the script.
BACKUP_DIR=`mkdir /tmp/"$TICKET_NUM"_EAR_BACKUP_"$(date "+%Y%m%d")"`
echo $BACKUP_DIR
But, the newly created directory is echoed in the screen. Anything Im missing here?
mkdir -v seems to print out the created directory, whereas mkdir is completely silent on my systems (tested on Mac OS X and Ubuntu Linux). However, you still need to parse out the directory name from this output:
mkdir /tmp/foo
(no output)
mkdir -v /tmp/foo
mkdir: created directory `/tmp/foo'
DIR=$(mkdir -v /tmp/foo | cut -d\ -f4- | tr -d "'\`")
echo $DIR
/tmp/foo
So in your case:
BACKUP_DIR=$( mkdir /tmp/"$TICKET_NUM"_EAR_BACKUP_"$(date "+%Y%m%d")" | cut -d\ -f4- | tr -d "'\`" )
You might want to use the -p switch in order to create the full directory hierarchy. (Yes, /tmp will exist on MOST machines, but sometimes things can really be screwed up...).
var=`cmd` catches output of cmd and stores in $var. But mkdir outputs nothing on success, so $BACKUP_DIR is empty.
BACKUP_DIR="/tmp/"$TICKET_NUM"_EAR_BACKUP_"$(date "+%Y%m%d")
mkdir $BACKUP_DIR
echo $BACKUP_DIR
This should work.