Вы можете решить свою проблему, используя внутреннюю переменную PIPESTATUS
(эта переменная имеет другие имена в оболочках без bash). Это позволяет иметь историю статусов выхода команд, переданных по каналу.
Вы уточнено в комментариях, что вы не использовали bash
, но используется zsh
вместо этого. Как таковой, некоторые из синтаксиса моего решения должны быть изменены, поскольку они обрабатывают переменную PIPESTATUS
по-разному.
В bash вы используете ${PIPESTATUS[0]}
, тогда как вы используете ${pipestatus[1]}
в zsh.
Первый подход, используя существующий псевдоним, может быть следующим:
makecclip && [ "${pipestatus[1]}" -eq "0" ] && echo "ok"
Это запускает echo
команду только если "${pipestatus[1]}"
равно 0 (без ошибок во время сборки)
Более удобным решением было бы использовать функцию вместо псевдонима для makecclip
. В файле ~/.bashrc
, вы могли бы написать:
makecclip() {
make |& tee >(sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | egrep ":[0-9]+:[0-9]+: error" | cut -d : -f1,2,3 | head -n 1 | xargs -0 echo -n | xclip -selection clipboard && xclip -selection clipboard -o)
return "${pipestatus[1]}"
}
Теперь makecclip && echo "ok"
будет работать, как ожидалось.
Тестовые случаи:
#!/bin/zsh
#do not run this test if there is an existing makefile in your current directory
rm -f makefile
makecclip() {
make |& tee >(sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | egrep ":[0-9]+:[0-9]+: error" | cut -d : -f1,2,3 | head -n 1 | xargs -0 echo -n | xclip -selection clipboard && xclip -selection clipboard -o)
# this part is only present to check the pipestatus values during the tests.
# In the real function, I wrote 'return ${pipestatus[1]}' instead.
a=(${pipestatus[@]})
echo ${a[@]}
return ${a[1]}
}
echo "# no makefile"
makecclip && echo "ok"
echo -e "\n# empty makefile"
touch makefile
makecclip && echo "ok"
echo -e "\n# dummy makefile entry"
echo -e 'a:\n\[email protected] "inside makefile"' > makefile
makecclip && echo "ok"
echo -e "\n# program with error makefile"
echo -e "int main(){error; return 0;}" > target.cc
echo -e 'a:\n\tgcc target.cc' > makefile
makecclip && echo "ok"
Выход:
$ ./test.sh
# no makefile
make: *** No targets specified and no makefile found. Stop.
2 0
# empty makefile
make: *** No targets. Stop.
2 0
# dummy makefile entry
inside makefile
0 0
ok
# program with error
gcc target.cc
target.cc: In function ‘int main()’:
target.cc:1:12: error: ‘error’ was not declared in this scope
int main(){error; return 0;}
^
makefile:2: recipe for target 'a' failed
make: *** [a] Error 1
target.cc:1:12
2 0
Я пробовал, но это не похоже на работу. Я думаю, что это действительно make, который изменит pipestatus, но я также должен перенаправить ошибку. Работало ли оно с вашими испытаниями? –
Да, на моем компьютере он отлично справился. Я редактировал свой вопрос, чтобы добавить те тесты, которые я использовал. – Aserre
@AdamHunyadi извините, мне потребовалось некоторое время, чтобы формализовать мои тестовые примеры в скрипте. Вы можете увидеть тест, который я выполнил, и полученный результат. – Aserre