I want to get some info from cmus-remote
if cmus
is running
#!/bin/zsh
pgrep cmus>& /dev/null
if [ $? -eq 0 ]; then
title=$(cmus-remote -Q | grep tag | grep title | sed 's/tag title //')
artist=$(cmus-remote -Q | grep tag | grep " artist " | sed 's/tag artist //')
album=$(cmus-remote -Q | grep tag | grep " album " | sed 's/tag album //')
track=$(cmus-remote -Q | grep tag | grep tracknumber | sed 's/tag tracknumber //')
echo $track $title - $artist - $album
else
echo ""
fi
the output for a running cmus is correct, when cmus isn't running I get
cmus-remote: cmus is not running
cmus-remote: cmus is not running
cmus-remote: cmus is not running
cmus-remote: cmus is not running
-
I have a workaround by appending >& /dev/null
on each corresponding line but that's not what I want, I would like the code not to be executed at all. And I don't the output from the else case.
pgrep cmus>& /dev/null
if [ $? -eq 0 ]; then
title=$(cmus-remote -Q | grep tag | grep title | sed 's/tag title //') > /dev/null 2>&1
artist=$(cmus-remote -Q | grep tag | grep " artist " | sed 's/tag artist //') > /dev/null 2>&1
album=$(cmus-remote -Q | grep tag | grep " album " | sed 's/tag album //') > /dev/null 2>&1
track=$(cmus-remote -Q | grep tag | grep tracknumber | sed 's/tag tracknumber //') >/ dev/null 2>&1
echo $track $title - $artist - $album
else
echo ""
fi
Adding > /dev/null 2>&1
2 refers to the second file descriptor of the process, ie stderr
.
>
means redirection.
&1
means the target of the redirection should be the same location as the first file descriptor, ie stdout
.
So this command first redirects stdout to /dev/null
and then redirects stderr there as well. This effectively silences all output (regular or error).
In your case cmus-remote: cmus is not running
is an stderr
so the redirection that you should use should be able to redirect both STDOUT
and STDERR
The actual problem that you seem to be having is that your pgrep is returning a hit while you're not expecting it to.
pgrep cmus>& /dev/null
if [ $? -eq 0 ]; then
//statements here are not evaluated if pgrep\'s exit status is not equal to 0
Your pgrep exit code = zero. but it is probably not an exact match (cmus) that was found. Try narrowing your search with pgrep (ie by the usage of the u or x flag)
tip: run your bash script with -X to see what the exit code actually was and compare them to the documented exit codes on https://linux.die.net/man/1/pgrep
The best authority on whether cmus
is running and whether cmus-remote
can retrieve any information is cmus-remote
. As such you could just replace pgrep cmus
with cmus-remote
as this will exit with return code 1, if cmus
:
cmus-remote >& /dev/null
if [ $? -eq 0 ]; then
# stuff
fi
Alternatively you could forego checking beforehand and reduce the amount of external commands called. Just try to parse the output cmus-remote -Q
and ignore output on stderr
:
#!/bin/zsh
cmus-remote -Q 2> /dev/null | awk '
BEGIN {
tags["album"] = "";
tags["artist"] = "";
tags["title"] = "";
tags["tracknumber"] = ""
}
$1 == "tag" && $2 in tags {
tag=$2;
$1=$2="";
sub(/ /,"");
tags[tag] = $0
}
END {
if (tag)
printf "%s %s - %s - %s\n", tags["tracknumber"], tags["title"], tags["artist"], tags["album"];
else
print ""
}'
This calls cmus-remote
just once and pipes stdout
to awk
(also called just once). If cmus
is not running the error message will be passed to /dev/null
. awk
then parses the output of cmus-remote -Q
and creates the desired output. If cmus
is not running or if there were no tags, it will print an empty string.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.