Jak mogę wyłączyć wszystkie dane wyjściowe polecenia za pomocą Bash?

296

Mam skrypt Bash, który uruchamia program z parametrami. Ten program generuje pewien status (robienie tego, robienie tego ...). Nie ma żadnej opcji, aby ten program był cichy. Jak mogę zapobiec wyświetlaniu skryptu?

Szukam czegoś takiego jak „echo off” systemu Windows .

6 bajtów
źródło

Odpowiedzi:

510

Poniżej wysyła standardowe dane wyjściowe do urządzenia zerowego (segmentu bitów).

scriptname >/dev/null

A jeśli chcesz również wysyłać tam komunikaty o błędach, użyj jednego z (pierwszy może nie działać we wszystkich powłokach):

scriptname &>/dev/null
scriptname >/dev/null 2>&1
scriptname >/dev/null 2>/dev/null

A jeśli chcesz nagrywać wiadomości, ale ich nie widzisz, zamień /dev/nullna rzeczywisty plik, taki jak:

scriptname &>scriptname.out

Dla kompletności pod Windows cmd.exe (gdzie „nul” jest odpowiednikiem „/ dev / null”), jest to:

scriptname >nul 2>nul
andynormancx
źródło
8
Zauważ, że „&>” jest charakterystyczne dla bash (i być może powłok C); Pociski Korn i Bourne wymagają 2> / dev / null lub 2> & 1 (aby wysłać stderr w to samo miejsce co stdout). Wygląda na to, że powłoka Korna interpretuje „&>” jako „uruchom rzeczy do & w tle, a następnie wykonaj przekierowanie we / wy na pustym poleceniu”.
Jonathan Leffler
2
Zauważ, że niektóre polecenia zapisują bezpośrednio do urządzenia końcowego, a nie do standardowego wyjścia / błędu. Aby przetestować, wprowadź echo foo > $(tty)skrypt i uruchom ./test.sh &> /dev/null- dane wyjściowe są nadal drukowane na terminalu. Oczywiście nie stanowi to problemu, jeśli piszesz skrypt, który nie używa takich poleceń.
l0b0
1
@ l0b0, czy istnieje sposób na różnicowanie tty skryptu (lub innego programu), aby wszystkie dane wyjściowe były przekierowywane niezależnie od twojego przykładu? Wiem, że screen i skrypt mogą zrobić coś takiego, ale oba są wybredne i różnią się od * nix do * nix.
Brent,
@yang /dev/nullistnieje w Cygwin, nie musisz go używać nul.
dimo414
47

Coś jak

script > /dev/null 2>&1

Zapobiegnie to standardowemu wyjściu i wyjściu błędu, przekierowując je na oba /dev/null.

Diego Sevilla
źródło
5
Osiągnięto to również dzięki & & jeśli chcesz zaoszczędzić trochę pisania;)
andynormancx
1
Mimo że dodaję to do mojego polecenia gs (GhostScript), nadal drukuje **** Ostrzeżenie: Plik ma uszkodzony znacznik %% EOF lub śmieci po %% EOF. Jakakolwiek rada?
ZurabWeb
To nie uruchamia procesu na systemach uniksowych, musiałem to zrobić2>/dev/null
alper
13

Próbować

: $(yourcommand)

: jest skrótem od „nic nie rób”.

$() to tylko twoje polecenie.

V0idSt4r
źródło
3
Bardzo interesujące, ale istnieje ograniczenie: zwracany kod statusu to zawsze 0(sukces). Zobaczmy przykład wykorzystujący polecenie, falsektóre zawsze zwraca 1(błąd). Na przykład ( echo foo | tee file ; false ) && echo barwyświetla foo. Korzystanie trick stłumić wyjście: ( : $(echo foo | tee file ; false) ) && echo bar. Ale wyświetla się, barco oznacza, że ​​kod statusu powrotu to 0(nie jest to kod statusu zwrotu z false). Zaktualizuj swoją odpowiedź, podając to ograniczenie. Na zdrowie
olibre
2
@olibre, co powiesz na DUMMY=$(yourcommand)? Nie ma wspomnianego ograniczenia. :)
semente
3
@semente Perfect: polecenie DUMMY=$( echo foo | tee file ; false ) && echo barniczego nie wyświetla. DUMMY=$( echo foo | tee file ; true ) && echo barWyświetli się polecenie bar. Daj mi znać, jeśli podasz odpowiedź, aby go zagłosować ;-) Pozdrawiam
olibre
9

Alternatywą, która może pasować w niektórych sytuacjach, jest przypisanie wyniku polecenia do zmiennej:

$ DUMMY=$( grep root /etc/passwd 2>&1 )
$ echo $?
0
$ DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
1

Ponieważ Bash i inne interpretery wiersza poleceń POSIX nie traktują przypisań zmiennych jako polecenia, kod powrotu bieżącego polecenia jest przestrzegany.

Uwaga: przypisanie za pomocą słowa kluczowego typesetlub declarejest uważane za polecenie, więc obliczony kod powrotu w przypadku, gdy jest to samo przypisanie, a nie polecenie wykonane w podpowłoce:

$ declare DUMMY=$( grep r00t /etc/passwd 2>&1 )
$ echo $?
0
Semente
źródło
6

Podobnie jak post andynormancx , użyj tego (jeśli pracujesz w środowisku Unix):

scriptname > /dev/null

Lub możesz użyć tego (jeśli pracujesz w środowisku Windows):

scriptname > nul
Lucas Gabriel Sánchez
źródło
1
Możesz faktycznie zrobić to lepiej w powłoce systemu Windows. Jeśli zamiast tego użyjesz „scriptname> nul”, nie będziesz nawet miał pliku do usunięcia, ponieważ „nul” jest odpowiednikiem / dev / null systemu Windows.
andynormancx
1
@andynormancx: Tego nienawidzę w układzie systemu plików Windows. „Rezerwuje” nazwy plików, takie jak NUL, COM1, LPT1, CON itp., Bez względu na katalog, w którym się znajdujesz (nawet jeśli jesteś w systemie plików, który może mieć takie nazwy plików, np. W udziałach sieciowych).
dreamlax
Nie sądzę, że faktycznie użyłem NUL od DOS 5.x, nagle zobaczyłem tę odpowiedź;)
andynormancx
Jeśli używasz > nulsystemu Windows z cygwin lub git bash, a teraz utkniesz w nulpliku, którego nie można usunąć, spróbuj wypróbować tę odpowiedź , działał jak urok.
Daemon Painter
4

Spójrz na ten przykład z The Linux Documentation Project :

3.6 Próbka: plik stderr i stdout 2

Spowoduje to umieszczenie każdego wyjścia programu w pliku. Jest to czasami odpowiednie dla wpisów cron, jeśli chcesz, aby polecenie przechodziło w absolutnej ciszy.

     rm -f $(find / -name core) &> /dev/null 

To powiedziawszy, możesz użyć tego prostego przekierowania:

/path/to/command &>/dev/null
ivanleoncz
źródło
1

W swoim skrypcie możesz dodać następujące wiersze, o których wiesz, że dają wynik:

some_code 2>>/dev/null

Albo możesz też spróbować

some_code >>/dev/null
Rohan Dsouza
źródło
1
nigdy nie widziałem >> do / dev / null .. z ciekawości .. Dlaczego to robisz?
Florian Berndl
Czy to tłumi całą wydajność?
Peter Mortensen
Dlaczego podwójne „>” (>> )?
Peter Mortensen