Jak ukryć dane wyjściowe polecenia w Bash

100

Chcę, aby moje skrypty Bash były bardziej eleganckie dla użytkownika końcowego. Jak ukryć dane wyjściowe, gdy Bash wykonuje polecenia?

Na przykład, gdy Bash wykonuje

yum install nano

Następujące informacje zostaną wyświetlone użytkownikowi, który wykonał Bash:

Loaded plugins: fastestmirror
base                                                     | 3.7 kB     00:00
base/primary_db                                          | 4.4 MB     00:03
extras                                                   | 3.4 kB     00:00
extras/primary_db                                        |  18 kB     00:00
updates                                                  | 3.4 kB     00:00
updates/primary_db                                       | 3.8 MB     00:02
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package nano.x86_64 0:2.0.9-7.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package         Arch              Version                Repository       Size
================================================================================
Installing:
 nano            x86_64            2.0.9-7.el6            base            436 k

Transaction Summary
================================================================================
Install       1 Package(s)

Total download size: 436 k
Installed size: 1.5 M
Downloading Packages:
nano-2.0.9-7.el6.x86_64.rpm                              | 436 kB     00:00
warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
 Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <[email protected]>
 Package: centos-release-6-4.el6.centos.10.x86_64 (@anaconda-CentOS-201303020151.x86_64/6.4)
 From   : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : nano-2.0.9-7.el6.x86_64                                      1/1
  Verifying  : nano-2.0.9-7.el6.x86_64                                      1/1

Installed:
  nano.x86_64 0:2.0.9-7.el6

Complete!

Teraz chcę to ukryć przed użytkownikiem i zamiast tego pokazać:

    Installing nano ......

Jak mogę wykonać to zadanie? Zdecydowanie pomogę uczynić skrypt bardziej przyjaznym dla użytkownika. W przypadku wystąpienia błędu należy go pokazać użytkownikowi.

Chciałbym wiedzieć, jak wyświetlić ten sam komunikat podczas wykonywania zestawu poleceń.

user2650277
źródło
4
echo "Installing nano ......"; yum install nano &> /dev/null
user000001

Odpowiedzi:

248

Użyj tego.

{
  /your/first/command
  /your/second/command
} &> /dev/null

Wyjaśnienie

Aby wyeliminować dane wyjściowe z poleceń, masz dwie opcje:

  • Zamknij plik deskryptora wyjściowego, co zapobiega przyjmowaniu dalszych danych wejściowych. To wygląda tak:

    your_command "Is anybody listening?" >&-

    Zwykle wyjście trafia do deskryptora pliku 1 (stdout) lub 2 (stderr). Jeśli zamkniesz deskryptor pliku, będziesz musiał to zrobić dla każdego deskryptora numerowanego, ponieważ &>(poniżej) jest specjalna składnia BASH niezgodna z >&-:

    /your/first/command >&- 2>&-

    Zwróć uwagę na kolejność: >&- zamyka stdout , czyli to, co chcesz zrobić; &>-przekierowuje stdout i stderr do pliku o nazwie -(myślnik), co nie jest tym, co chcesz zrobić. Na początku będzie wyglądać tak samo, ale ten drugi tworzy bezpański plik w katalogu roboczym. Łatwo to zapamiętać: >&2przekierowuje stdout do deskryptora 2 (stderr), >&3przekierowuje stdout do deskryptora 3 i >&-przekierowuje stdout do ślepego zaułka (tj. Zamyka stdout).

    Uważaj również, że niektóre polecenia mogą nie obsługiwać szczególnie dobrze zamkniętego deskryptora pliku („błąd zapisu: zły deskryptor pliku”), dlatego lepszym rozwiązaniem może być ...

  • Przekieruj dane wyjściowe do/dev/null , które akceptuje wszystkie dane wyjściowe i nic z nimi nie robi. To wygląda tak:

    your_command "Hello?" > /dev/null

    Aby uzyskać przekierowanie wyjścia do pliku, możesz bardzo zwięźle skierować stdout i stderr w to samo miejsce, ale tylko w bash:

    /your/first/command &> /dev/null

Na koniec, aby zrobić to samo dla wielu poleceń naraz, umieść całość w nawiasach klamrowych. Bash traktuje to jako grupę poleceń , agregując deskryptory plików wyjściowych, abyś mógł przekierować wszystkie na raz. Jeśli zamiast tego znasz podpowłoki używające ( command1; command2; )składni, zauważysz, że nawiasy klamrowe zachowują się prawie dokładnie w ten sam sposób, z wyjątkiem tego, że jeśli nie umieścisz ich w potoku, nawiasy klamrowe nie utworzą podpowłoki, a tym samym pozwolą ci ustawić zmienne wewnątrz.

{
  /your/first/command
  /your/second/command
} &> /dev/null

Więcej informacji, opcji i składni można znaleźć w podręczniku bash dotyczącym przekierowań .

Jeff Bowman
źródło
Cześć, wiem, że to stare pytanie, ale czy można to samo zrobić warunkowo? Jak chcę ukryć dane wyjściowe pod pewnymi warunkami? Wiem, że mogę powielić tę samą część w ramach if-else, ale czy jest na to lepszy sposób?
Usama Zafar
@UsamaZafar miałbym to zrobić poprzez ustawienie zmiennej ( „shell parametru” ), który zostanie ustawiony na albo /dev/nulli /dev/stdout(lub /path/to/a/logfile) warunkowo wcześniej w skrypcie, a następnie przekierowanie do tego miejsca przeznaczenia przy użyciu &> $output_dest(lub cokolwiek to nazwę). Jeśli nie chcesz w takim przypadku łączyć stdout i stderr, możesz przekierować je osobno, np > $output_dest 2> $errors_dest.
Jeff Bowman,
35

Możesz przekierować standardowe wyjście do / dev / null.

yum install nano > /dev/null

Lub możesz przekierować zarówno stdout, jak i stderr,

yum install nano &> /dev/null.

Ale jeśli program ma cichą opcję, to jeszcze lepiej.

ktm5124
źródło
23

Proces zwykle ma dwa wyjścia do ekranu: stdout (standardowe wyjście) i stderr (błąd standardowy).

Zwykle wiadomości informacyjne trafiają do sdout, a błędy i alertystderr .

Możesz wyłączyć stdoutdla polecenia, wykonując

MyCommand >/dev/null

i wyłącz stderr, wykonując:

MyCommand 2>/dev/null

Jeśli chcesz wyłączyć oba , możesz:

MyCommand 2>&1 >/dev/null

2>&1Mówi wysłać stderr do tego samego miejsca, co standardowe wyjście.

LeOn - Han Li
źródło
8

Możesz przekierować dane wyjściowe do /dev/null. Aby uzyskać więcej informacji na temat / dev / null, przeczytaj ten link .

Możesz ukryć wyjście polecenia na następujące sposoby:

echo -n "Installing nano ......"; yum install nano > /dev/null; echo " done."; 

Przekieruj standardowe wyjście do /dev/null, ale nie do standardowego błędu. Spowoduje to wyświetlenie błędów występujących podczas instalacji, na przykład jeśli yumnie można znaleźć pakietu.

echo -n "Installing nano ......"; yum install nano &> /dev/null; echo " done.";

Chociaż ten kod nie pokaże niczego w terminalu, ponieważ zarówno standardowy błąd, jak i standardowe wyjście są przekierowywane, a tym samym null do /dev/null.

Giuseppe Pes
źródło
1
Świetny udział ... stary, czy możesz mi pokazać, jak wyprowadzić tę samą wiadomość tylko raz dla zestawu poleceń
user2650277
5

>/dev/null 2>&1wyciszy zarówno stdoutistderr

yum install nano >/dev/null 2>&1
Quanlong
źródło
4

W tym przypadku nie powinieneś używać basha, aby pozbyć się wyniku. Mniam ma opcję-q która blokuje wyjście.

Z pewnością będziesz też chciał użyć -y

echo "Installing nano..."
yum -y -q install nano

Aby zobaczyć wszystkie opcje yum, użyj man yum.

kkeller
źródło
Dzięki, założyłem, że yum miał jeden od czasu użycia apt-get -qq również do stłumienia. To było pomocne w tym, co robię.
Hyperion,
0
.SILENT:

Wpisz „.SILENT:” na początku skryptu bez dwukropków.

Arif
źródło