Come nascondere l'output del comando in Bash


99

Voglio rendere i miei script Bash più eleganti per l'utente finale. Come nascondo l'output quando Bash esegue i comandi?

Ad esempio, quando Bash viene eseguito

yum install nano

Quanto segue verrà mostrato all'utente che ha eseguito il 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) <centos-6-key@centos.org>
 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!

Ora voglio nasconderlo all'utente e mostrare invece:

    Installing nano ......

Come posso eseguire questa operazione? Ti aiuterò sicuramente a rendere lo script più facile da usare. Nel caso in cui si verifichi un errore, dovrebbe essere mostrato all'utente.

Vorrei sapere come mostrare lo stesso messaggio mentre viene eseguita una serie di comandi.


4
echo "Installing nano ......"; yum install nano &> /dev/null
user000001


Risposte:


246

Usa questo.

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

Spiegazione

Per eliminare l'output dai comandi, hai due opzioni:

  • Chiude il file descrittore di output, che gli impedisce di accettare ulteriori input. Assomiglia a questo:

    your_command "Is anybody listening?" >&-

    Di solito, l'output va al descrittore di file 1 (stdout) o 2 (stderr). Se chiudi un descrittore di file, dovrai farlo per ogni descrittore numerato, poiché &>(sotto) è una sintassi BASH speciale incompatibile con >&-:

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

    Fai attenzione a notare l'ordine: >&- chiude stdout , che è quello che vuoi fare; &>-reindirizza stdout e stderr a un file chiamato -(trattino), che non è quello che vuoi fare. All'inizio sembrerà lo stesso, ma quest'ultimo crea un file vagante nella directory di lavoro. È facile da ricordare: >&2reindirizza lo stdout al descrittore 2 (stderr), >&3reindirizza lo stdout al descrittore 3 e >&-reindirizza lo stdout a un vicolo cieco (cioè chiude lo stdout).

    Inoltre, fai attenzione che alcuni comandi potrebbero non gestire un descrittore di file chiuso particolarmente bene ("errore di scrittura: descrittore di file non valido"), motivo per cui la soluzione migliore potrebbe essere quella di ...

  • Reindirizza l'output a/dev/null , che accetta tutto l'output e non fa nulla con esso. Assomiglia a questo:

    your_command "Hello?" > /dev/null

    Per il reindirizzamento dell'output a un file, puoi indirizzare sia stdout che stderr nello stesso posto in modo molto conciso, ma solo in bash:

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

Infine, per fare lo stesso per più comandi contemporaneamente, racchiudi il tutto tra parentesi graffe. Bash lo tratta come un gruppo di comandi , aggregando i descrittori dei file di output in modo da poterli reindirizzare tutti in una volta. Se invece hai familiarità con le subshell usando la ( command1; command2; )sintassi, scoprirai che le parentesi graffe si comportano quasi esattamente allo stesso modo, tranne che a meno che non le coinvolgi in una pipe, le parentesi graffe non creeranno una subshell e quindi ti permetteranno di impostare le variabili all'interno.

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

Vedere il manuale di bash sui reindirizzamenti per maggiori dettagli, opzioni e sintassi.


Ciao, so che è una vecchia domanda ma si può fare lo stesso in modo condizionale? Come se volessi nascondere l'output in determinate condizioni? So di poter replicare la stessa parte in if-else, ma c'è un modo migliore per farlo?
usamazf

@UsamaZafar Lo farei impostando una variabile ( "parametro shell" ), che hai impostato su /dev/nullo /dev/stdout(o /path/to/a/logfile) in modo condizionale in precedenza nello script, e quindi reindirizzando a quella destinazione usando &> $output_dest(o qualunque cosa tu chiami). Se non vuoi combinare stdout e stderr in quel caso, puoi reindirizzarli separatamente come > $output_dest 2> $errors_dest.
Jeff Bowman

35

Puoi reindirizzare lo stdout a / dev / null.

yum install nano > /dev/null

Oppure puoi reindirizzare sia stdout che stderr,

yum install nano &> /dev/null.

Ma se il programma ha un'opzione silenziosa, è ancora meglio.


23

Un processo normalmente ha due output da vagliare: stdout (standard out) e stderr (standard error).

Normalmente i messaggi informativi vanno a sdoute gli errori e gli avvisi vanno a stderr.

Puoi disattivare stdoutper un comando facendo

MyCommand >/dev/null

e spegnerlo stderrfacendo:

MyCommand 2>/dev/null

Se vuoi disattivarli entrambi , puoi fare:

MyCommand 2>&1 >/dev/null

La 2>&1dice inviare stderr allo stesso posto di stdout.


8

Puoi reindirizzare l'output a /dev/null. Per maggiori informazioni su / dev / null leggere questo collegamento .

È possibile nascondere l'output di un comando nei seguenti modi:

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

Reindirizza l'output standard a /dev/null, ma non l'errore standard. Questo mostrerà gli errori che si verificano durante l'installazione, ad esempio se yumnon è possibile trovare un pacchetto.

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

Sebbene questo codice non mostrerà nulla nel terminale poiché sia ​​l'errore standard che lo standard output vengono reindirizzati e quindi annullati a /dev/null.


1
Grande condivisione .... amico, puoi mostrarmi come inviare lo stesso messaggio solo una volta per una serie di comandi
user2650277

5

>/dev/null 2>&1disattiverà sia stdoutestderr

yum install nano >/dev/null 2>&1

4

Non dovresti usare bash in questo caso per sbarazzarti dell'output. Yum ha un'opzione -qche sopprime l'output.

Sicuramente vorrai anche usare -y

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

Per vedere tutte le opzioni per yum, usa man yum.


Grazie, pensavo che yum ne avesse uno poiché apt-get used -qq pure per sopprimere. Questo è stato utile per quello che sto facendo.
Hyperion

0
.SILENT:

Digita ".SILENT:" all'inizio dello script senza i due punti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.