Команда запуска zsh, если процесс запущен
Я хочу получить информацию от cmus-remote
если cmus
бежит
#!/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
вывод для запущенного cmus правильный, когда cmus не работает, я получаю
cmus-remote: cmus is not running
cmus-remote: cmus is not running
cmus-remote: cmus is not running
cmus-remote: cmus is not running
-
У меня есть обходной путь, добавив >& /dev/null
в каждой соответствующей строке, но это не то, что я хочу, я бы хотел, чтобы код вообще не выполнялся. И я не делаю вывод из другого случая.
3 ответа
Реальная проблема, с которой вы, похоже, сталкиваетесь, заключается в том, что ваш pgrep возвращает удар, а вы этого не ожидаете.
pgrep cmus>& /dev/null
if [ $? -eq 0 ]; then
//statements here are not evaluated if pgrep\'s exit status is not equal to 0
Ваш код выхода pgrep = ноль. но это, вероятно, не точное совпадение (cmus), которое было найдено. Попробуйте сузить область поиска с помощью pgrep (т. Е. С помощью флага u или x)
Совет: запустите ваш bash-скрипт с ключом -X, чтобы увидеть, что на самом деле был код выхода, и сравнить его с документированными кодами выхода на https://linux.die.net/man/1/pgrep
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
Добавление > /dev/null 2>&1
2 относится ко второму файловому дескриптору процесса, т.е. stderr
,
>
означает перенаправление.
&1
означает, что цель перенаправления должна быть в том же месте, что и первый дескриптор файла, т.е. stdout
,
Таким образом, эта команда сначала перенаправляет стандартный вывод /dev/null
а затем перенаправляет туда stderr. Это эффективно заглушает весь вывод (обычный или с ошибкой).
В твоем случае cmus-remote: cmus is not running
является stderr
поэтому перенаправление, которое вы должны использовать, должно быть в состоянии перенаправить оба STDOUT
а также STDERR
Лучший авторитет в том, cmus
работает ли cmus-remote
может получить любую информацию cmus-remote
, Таким образом, вы можете просто заменить pgrep cmus
с cmus-remote
как это выйдет с кодом возврата 1, если cmus
:
cmus-remote >& /dev/null
if [ $? -eq 0 ]; then
# stuff
fi
В качестве альтернативы вы можете отказаться от проверки заранее и уменьшить количество вызываемых внешних команд. Просто попробуйте разобрать вывод cmus-remote -Q
и игнорировать вывод на 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 ""
}'
Это звонки cmus-remote
только один раз и трубы stdout
в awk
(также вызывается только один раз). Если cmus
сообщение об ошибке не будет передано /dev/null
, awk
затем анализирует вывод cmus-remote -Q
и создает желаемый результат. Если cmus
не запущен или если тегов не было, будет выведена пустая строка.