Reputation: 90
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.
Upvotes: 0
Views: 892
Reputation: 18339
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.
Upvotes: 0
Reputation: 935
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, i.e. stderr
.
>
means redirection.
&1
means the target of the redirection should be the same location as the first file descriptor, i.e. 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
Upvotes: 0
Reputation: 78
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 (i.e. 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
Upvotes: 1