придушити більш строгі повідомлення в баш-скрипті


48

Розглянемо таку (злегка нерозумно) назву сценарію 'test1.sh':

#/bin/bash
#
sleep 10 &
echo sleep pid = $!
pkill sleep

Коли я запускаю його, я отримую не тільки вихід відлуння, але й повідомлення Баша про смерть сну на stderr:

$ ./test1.sh
sleep pid = 3551
./test1.sh: line 5:  3551 Terminated              sleep 10

У цьому випадку я хотів би придушити роздруківку до більш жорсткої. Я знаю, що можу це зробити в командному рядку, як у:

$ ./test1.sh 2> /dev/null

... але чи є спосіб придушити це всередині сценарію? (Я знаю, що я міг би перетворити його у другий сценарій і мати його, щоб обгортка перенаправляла його, але повинно бути щось простіше ...)


ви намагалися додати переспрямування 2> / dev / null після сну pkill?
rahul

@rahul: так, я зробив - pkill не генерує повідомлення, баш.
безстрашний_фол

Я використовував kill замість pkill і не отримую більш жорсткий. дивно ..
rahul

@rahul: чи може це бути вбудованим проти небудованого в речі? Ви пробували і з pkill?
безстрашний_фул

так, я вірю, що це так. Я отримую ту ж помилку з pkill, але не з kill. Під час використання kill я використав pid замість імені proc.
rahul

Відповіді:


72

Ти правий; pkill не генерує повідомлення, bash є. Ви пропонуєте це

$ ./test1.sh 2> /dev/null

є можливим рішенням. Як зазначає UVV, еквівалентна дія всередині сценарію є

exec 2> /dev/null

Це перенаправляє stderr для сценарію /dev/null з цього твердження, поки він не буде змінений назад. Незграбні способи зміни його назад включають

exec 2> /dev/tty

який перенаправляє stderr до терміналу. Це, мабуть, (але не обов'язково) там, де воно було спочатку.

Або

exec 2>&1

що встановлює stderr таким же, як і stdout, і, ймовірно, помиляється.

Більш надійний спосіб

exec 3> & 2
exec 2> / dev / null
(робити речі там, де ви не хочете бачити stderr.) 
exec 2> & 3

який зберігає оригінальний stderr у дескрипторі файлів 3, а пізніше відновлює його.

Інші способи придушити лише оголошення смерті процесу включають

(sleep 10 & pkill sleep) 2> /dev/null

і

{ sleep 10 & pkill sleep;} 2> /dev/null

які змінюють stderr лише для згрупованих команд.


Це така чудова, детальна відповідь. Дякую вам сер!
Кінан Лоуренс

Чи існують якісь небезпеки, пов’язані із збереженням stdinта stderrновими дескрипторами файлів, надсиланням оригінальних дескрипторів, /dev/nullа потім їх відновленням?
Олексій Магура

Ну, я припускаю, що якщо ви запустили програму, яка (невідомо вам) написала файл дескриптора 3 (або 4), ця операція не відбудеться за звичайних обставин. Але програма може бути написана для того, щоб ігнорувати збій та продовжувати, не повідомляючи про це; тоді ти ніколи не дізнаєшся. Але якщо ваш дескриптор файлу 1 (або 2) був "припаркований" у дескрипторі файлів 3 (або 4), то ця програма раптом запише в stdout або stderr вашого сценарію. Але це дуже надуманий приклад і все ще мінімальна небезпека. Ви щось мали на увазі?
Скотт

1
FWIW, я віддаю перевагу групованому командному підходу Скотта, тобто{ sleep 10 & pkill sleep;} 2> /dev/null
безстрашний_фол

9

Згідно з цим ви можете зробити щось на кшталт наступного:

#!/bin/bash
exec 2>/dev/null
ls -al test
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.