Jak zapisać dane wyjściowe terminala w pliku?

688

Jak zapisać dane wyjściowe polecenia w pliku?

Czy istnieje sposób bez użycia oprogramowania? Chciałbym wiedzieć jak.

led-Zepp
źródło

Odpowiedzi:

735

Tak, jest to możliwe, po prostu przekieruj dane wyjściowe do pliku:

SomeCommand > SomeFile.txt  

Lub jeśli chcesz dołączyć dane:

SomeCommand >> SomeFile.txt

Jeśli chcesz stderrrównież użyć tego:

SomeCommand &> SomeFile.txt  

lub to dołączyć:

SomeCommand &>> SomeFile.txt  

jeśli chcesz, aby na konsoli i w pliku były wyświetlane zarówno stderrdane wyjściowe, jak i plik, użyj tego:

SomeCommand 2>&1 | tee SomeFile.txt

(Jeśli chcesz tylko dane wyjściowe, upuść 2powyższe)

Seth
źródło
15
Zauważ, że someCommand 2> someFile.txta someCommand 2>> someFile.txttakże przekierowuje stterrdo someFile.txt
Slothworks
Próbuję to zrobić za pomocą polecenia gcc, ale to nie działa. Działa z innymi poleceniami, ale nie z tym. Po prostu tworzy plik wyjściowy bez niczego.
Nikos
@ Nik-Lz Często dzieje się tak, ponieważ polecenie wysyła wszystkie dane wyjściowe na stderr. Jeśli gcc generuje komunikaty o błędach, wydaje się to prawdopodobne. Zobacz komentarz Slothworks, jak uchwycić stderr zamiast stdout.
Jonathan Hartley
1
Uwaga: aby uzyskać wynik makepolecenia w pliku, wymagana jest następująca składnia: make > someFile.txt 2>&1(źródło: linuxquestions.org/questions/linux-newbie-8/... )
Gabriel Staples
Mam problem polegający na tym, że przestaje on zapisywać, gdy plik osiągnie około 8 MB. Czy to znany limit?
relG
863

Aby zapisać dane wyjściowe polecenia w pliku, jest w zasadzie 10 najczęściej używanych sposobów.

Przegląd:

Uwaga: n.e.w kolumnie składni oznacza „nie istnieje”.
Jest sposób, ale jest zbyt skomplikowany, aby zmieścić się w kolumnie. Pomocny link można znaleźć w sekcji Lista na ten temat.

          || visible in terminal ||   visible in file   || existing
  Syntax  ||  StdOut  |  StdErr  ||  StdOut  |  StdErr  ||   file   
==========++==========+==========++==========+==========++===========
    >     ||    no    |   yes    ||   yes    |    no    || overwrite
    >>    ||    no    |   yes    ||   yes    |    no    ||  append
          ||          |          ||          |          ||
   2>     ||   yes    |    no    ||    no    |   yes    || overwrite
   2>>    ||   yes    |    no    ||    no    |   yes    ||  append
          ||          |          ||          |          ||
   &>     ||    no    |    no    ||   yes    |   yes    || overwrite
   &>>    ||    no    |    no    ||   yes    |   yes    ||  append
          ||          |          ||          |          ||
 | tee    ||   yes    |   yes    ||   yes    |    no    || overwrite
 | tee -a ||   yes    |   yes    ||   yes    |    no    ||  append
          ||          |          ||          |          ||
 n.e. (*) ||   yes    |   yes    ||    no    |   yes    || overwrite
 n.e. (*) ||   yes    |   yes    ||    no    |   yes    ||  append
          ||          |          ||          |          ||
|& tee    ||   yes    |   yes    ||   yes    |   yes    || overwrite
|& tee -a ||   yes    |   yes    ||   yes    |   yes    ||  append

Lista:

  • command > output.txt

    Standardowy strumień wyjściowy zostanie przekierowany tylko do pliku, nie będzie widoczny w terminalu. Jeśli plik już istnieje, zostanie zastąpiony.

  • command >> output.txt

    Standardowy strumień wyjściowy zostanie przekierowany tylko do pliku, nie będzie widoczny w terminalu. Jeśli plik już istnieje, nowe dane zostaną dołączone na końcu pliku.

  • command 2> output.txt

    Standardowy strumień błędów zostanie przekierowany tylko do pliku, nie będzie widoczny w terminalu. Jeśli plik już istnieje, zostanie zastąpiony.

  • command 2>> output.txt

    Standardowy strumień błędów zostanie przekierowany tylko do pliku, nie będzie widoczny w terminalu. Jeśli plik już istnieje, nowe dane zostaną dołączone na końcu pliku.

  • command &> output.txt

    Zarówno standardowe wyjście, jak i standardowy strumień błędów zostaną przekierowane tylko do pliku, nic nie będzie widoczne w terminalu. Jeśli plik już istnieje, zostanie zastąpiony.

  • command &>> output.txt

    Zarówno standardowe wyjście, jak i standardowy strumień błędów zostaną przekierowane tylko do pliku, nic nie będzie widoczne w terminalu. Jeśli plik już istnieje, nowe dane zostaną dołączone na końcu pliku.

  • command | tee output.txt

    Standardowy strumień wyjściowy zostanie skopiowany do pliku, nadal będzie widoczny w terminalu. Jeśli plik już istnieje, zostanie zastąpiony.

  • command | tee -a output.txt

    Standardowy strumień wyjściowy zostanie skopiowany do pliku, nadal będzie widoczny w terminalu. Jeśli plik już istnieje, nowe dane zostaną dołączone na końcu pliku.

  • (*)

    Bash nie ma skróconej składni, która pozwala na przesłanie tylko StdErr do drugiego polecenia, które byłoby potrzebne tutaj w połączeniu z teeponownie do uzupełnienia tabeli. Jeśli naprawdę potrzebujesz czegoś takiego, spójrz na „Jak stderr rur, a nie stdout?” w przypadku przepełnienia stosu na kilka sposobów, w jaki sposób można to zrobić, np. poprzez zamianę strumieni lub stosowanie zastępowania procesów.

  • command |& tee output.txt

    Zarówno standardowe dane wyjściowe, jak i standardowe strumienie błędów zostaną skopiowane do pliku, nadal będą widoczne w terminalu. Jeśli plik już istnieje, zostanie zastąpiony.

  • command |& tee -a output.txt

    Zarówno standardowe dane wyjściowe, jak i standardowe strumienie błędów zostaną skopiowane do pliku, nadal będą widoczne w terminalu. Jeśli plik już istnieje, nowe dane zostaną dołączone na końcu pliku.

Bajt Dowódca
źródło
66
Dzięki za stół, jest świetnie! To powinna być najlepsza odpowiedź
DevShark
3
@ karthick87 Nie jest to tak naprawdę związane z pytaniem o przekierowanie danych wyjściowych do pliku, ponieważ po prostu przekierowuje jeden strumień do drugiego. 2>&1przekierowuje STDERR do STDOUT, 1>&2przekierowuje STDOUT do STDERR i 3>&1przekierowuje strumień 3 do STDERR.
Bajt Dowódca
18
Tylko uwaga, że ​​„| &” nie działało dla mnie na macOS. Wynika to z faktu, że ma starszą wersję bash (tak myślę). Mniej eleganckie „2> i 1 |” działa dobrze
Danny Parker
2
@ByteCommander pojawia się błąd: sh: 1: Syntax error: "&" unexpectedkiedy używam |& teeze skryptu Python na serwerze c9.io. Wygląda na to, że używana jest inna powłoka. echo $SHELLpokazuje /bin/bashi $SHELL --versionpokazuje wydanie w wersji 4.3.11 (1). Próbowałem #!/bin/bashw moim skrypcie Python, ale nadal mam sh: 1: Syntax error. Dostałem to, czego potrzebowałem, więc rezygnuję z sortowania dziwności między shi bashna moim serwerze. Dzięki.
samkhan13
1
@ samkhan13 wygląda na to, że działasz, sha nie bash(lub może bashw shtrybie ...). Możesz sprawdzić, z czego dokładnie korzysta Twój bieżący proces powłoki ps -p $$ -o cmd=, ponieważ echo $SHELLjest on niewiarygodny i wyświetli powłokę logowania, ignorując, czy mogłeś uruchomić inną podpowłokę.
Bajt Dowódca
108

Możesz także użyć, teeaby wysłać dane wyjściowe do pliku:

command | tee ~/outputfile.txt

Niewielka modyfikacja złapie również stderr:

command 2>&1 | tee ~/outputfile.txt

lub nieco krótszy i mniej skomplikowany:

command |& tee ~/outputfile.txt

teejest przydatny, jeśli chcesz mieć możliwość przechwytywania danych wyjściowych poleceń podczas oglądania ich na żywo .

Aaron
źródło
Mówi, że znak & jest nieoczekiwany i nie zapisuje dziennika w tym samym czasie, co polecenie. Używam tego w pliku bash, czy to robi jakąkolwiek różnicę?
tim687
@ tim687 Usunąłem tę edycję. Przepraszam za to ... nie było częścią mojej pierwotnej odpowiedzi.
Aaron,
@Aaron Thanks! tee dołączy plik w czasie rzeczywistym, prawda? Mam skrypt kopii zapasowej, którego używam do tworzenia kopii zapasowych komputera, lol, ale rejestrowanie nie odbywa się w czasie rzeczywistym. Mój komputer przechodzi w tryb uśpienia po zakończeniu tworzenia kopii zapasowej, a plik dziennika jest pusty. Czy powinienem użyć innego polecenia do zarejestrowania poleceń?
tim687
jak interpretować znaczenie 2>&1?
Mahesha999
@ Mahesha999 2 to deskryptor pliku dla STDERR, a 1 to STDOUT. Tak, że 2> i 1 wysyła STDERR do STDOUT. To SO pytanie wyjaśnia to całkiem dobrze: stackoverflow.com/questions/818255/…
Aaron
20

Możesz przekierować dane wyjściowe polecenia do pliku:

your_command >/path/to/file

Aby dołączyć dane wyjściowe polecenia do pliku zamiast go zastąpić, użyj:

your_command >>/path/to/file
chaos
źródło
Wielkie dzięki ! czy są jakieś ograniczenia? jak maksymalny rozmiar pliku?
led-Zepp
3
Maksymalny rozmiar pliku jest po prostu ograniczony przez system plików
chaos
Ta odpowiedź nie uratuje stderr. Użyj &>, patrz stackoverflow.com/questions/637827/... i tldp.org/LDP/abs/html/io-redirection.html
Panther
3
OP nigdy nie poprosił o uratowanie stderr
chaosu
Mówi „Nie ma takiego pliku ani katalogu”. Czy możliwe jest także automatyczne tworzenie katalogów?
Qwerty
14

Ulepszenie do rozważenia -

Różne skrypty wstrzykują kolorowe kody wyjściowe, które mogą nie wymagać zaśmiecania pliku dziennika.

Aby to naprawić, możesz użyć programu sed do usunięcia tych kodów. Przykład:

command 2>&1 | sed -r 's/'$(echo -e "\033")'\[[0-9]{1,2}(;([0-9]{1,2})?)?[mK]//g' | tee ~/outputfile.txt
Sean Huber
źródło
1
Jak zapisać dane wyjściowe w sposób, który pozwala zachować kolory? Chciałbym zaimportować wynik polecenia w libreoffice i zachować kolory.
madrang
@madrang: Teraz czytam tylko twój komentarz, ale może ci się przydać ta odpowiedź .
Sylvain Pineau,
Och, prawie dokładnie to, czego szukam. Jak wydrukować również na ekranie wydruk?
Sigur,
1
Zauważ, że wiele poleceń, które generują pokolorowane dane wyjściowe, takie jak lsi grep, obsługuje --color=auto, które wysyłają kody kolorów tylko wtedy, gdy standardowe wyjście jest terminalem.
Eliah Kagan,
5

W przypadku cronzadań itp. Chcesz uniknąć rozszerzeń Bash. Odpowiednimi shoperatorami przekierowania POSIX są

Bash          POSIX
------------  --------------
foo &> bar    foo >bar 2>&1
foo &>> bar   foo >>bar 2>&1
foo |& bar    foo 2>&1 | bar

Zauważysz, że funkcja POSIX jest w pewnym sensie prostsza i bardziej prosta. &>Składnia została zapożyczona z cshktórego powinien już przekonać, że to zły pomysł.

potrójny
źródło
1

some_command | tee command.logi some_command > command.logmają problem polegający na tym, że nie zapisują danych wyjściowych polecenia w command.logpliku w czasie rzeczywistym.

Aby uniknąć tego problemu i zapisać dane wyjściowe polecenia w czasie rzeczywistym, możesz dołączyć unbufferdołączony expectpakiet.


Przykład:

sudo apt-get install expect
unbuffer some_command | tee command.log
unbuffer some_command > command.log

Zakładając, że log.pyzawiera:

import time
print('testing')
time.sleep(100) # sleeping for 100 seconds

możesz uruchomić unbuffer python log.py | tee command.loglubunbuffer python log.py > command.log

Więcej informacji: Jak zapisać dane wyjściowe polecenia w pliku w czasie rzeczywistym?

Franck Dernoncourt
źródło
Zapisują dane wyjściowe po ich otrzymaniu, problem polega na tym, że Python włącza buforowanie, gdy dane wyjściowe nie są w TTY. Inne opcje wyłączania tego w Pythonie: stackoverflow.com/q/107705/2072269
muru