2016-11-25 5 views
1

Я хотел бы изменить одну из моих недавних псевдонимов Bash для пересылки ошибок. Вот псевдоним:Изменить команды zsh на пересылку ошибок

alias 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) 

Этот код отображает результаты компиляции C++, а затем удаляет форматирование и отображает и добавляет в буфер первое место ошибки (если есть).

Однако, я хотел бы использовать этот код, как это:

makecclip && bin/someexecutablecreated 

Это хотя руины оператор &&, так как он всегда работает Bin/someexecutablecreated, даже если в настоящее время существует ошибка компиляции. Как добавить изменения в код, чтобы установить флаг ошибки, когда список ошибок (вещи, сохраненные в буфер обмена и эхо) не пуст?

ответ

1

Вы можете решить свою проблему, используя внутреннюю переменную 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 
+0

Я пробовал, но это не похоже на работу. Я думаю, что это действительно make, который изменит pipestatus, но я также должен перенаправить ошибку. Работало ли оно с вашими испытаниями? –

+0

Да, на моем компьютере он отлично справился. Я редактировал свой вопрос, чтобы добавить те тесты, которые я использовал. – Aserre

+0

@AdamHunyadi извините, мне потребовалось некоторое время, чтобы формализовать мои тестовые примеры в скрипте. Вы можете увидеть тест, который я выполнил, и полученный результат. – Aserre

 Смежные вопросы

  • Нет связанных вопросов^_^