Musiałem napisać skrypt, aby wprowadzić wieloliniowe dane wejściowe do programu ( psql
).
Po trochę googlingu znalazłem następującą składnię:
cat << EOF | psql ---params
BEGIN;
`pg_dump ----something`
update table .... statement ...;
END;
EOF
To poprawnie konstruuje łańcuch wieloliniowy (od BEGIN;
do END;
włącznie) i potokuje go jako dane wejściowe do psql
.
Ale nie mam pojęcia, jak / dlaczego to działa, czy ktoś mógłby wyjaśnić?
Mam na myśli przede wszystkim cat << EOF
, znam dane >
wyjściowe do pliku, >>
dołącza się do pliku, <
odczytuje dane wejściowe z pliku.
Co <<
dokładnie robi?
I czy jest do tego strona podręcznika?
cat
. Spróbujpsql ... << EOF ...
Zobacz także „ciągi tutaj”. mywiki.wooledge.org/BashGuide/InputAndOutput?#Here_Stringscat
odczytywania polecenia stding (po przesłaniu do niego) lub odczytuje plik odpowiadający argumentom wiersza poleceńOdpowiedzi:
Nazywa się to formatem heredoc , aby zapewnić ciąg do standardowego wejścia. Więcej informacji na stronie https://en.wikipedia.org/wiki/Here_document#Unix_shells .
Od
man bash
:źródło
<<-
należy pamiętać, że tylko wiodące znaki tabulacji są usuwane - nie znaki tabulacji miękkiej. Jest to jeden z tych rzadkich przypadków, kiedy naprawdę potrzebujesz znaku tabulacji. Jeśli w pozostałej części dokumentu używane są miękkie tabulatory, pamiętaj, aby wyświetlać niewidoczne znaki oraz (np.) Kopiować i wklejać tabulatory. Jeśli zrobisz to dobrze, podświetlanie składni powinno poprawnie przechwytywać końcowy ogranicznik.cat <<EOF
Składnia jest bardzo przydatna podczas pracy z tekstem multi-line w bash, np. podczas przypisywania ciągu wielowierszowego do zmiennej powłoki, pliku lub potoku.Przykłady
cat <<EOF
użycia składni w Bash:1. Przypisz ciąg wieloliniowy do zmiennej powłoki
$sql
Zmienna posiada obecnie znaki nowej linii zbyt. Możesz to zweryfikować za pomocąecho -e "$sql"
.2. Przekaż ciąg wiersza do pliku w Bash
print.sh
Plik zawiera teraz:3. Prześlij ciąg wieloliniowy do rury w Bash
b.txt
Plik zawierabar
ibaz
linie. To samo wyjście jest drukowane nastdout
.źródło
W twoim przypadku „EOF” jest znany jako „Here Tag”. Zasadniczo
<<Here
informuje powłokę, że zamierzasz wprowadzić ciąg wielowierszowy, aż do „znacznika”Here
. Możesz nazwać ten tag, jak chcesz, częstoEOF
lubSTOP
.Niektóre zasady dotyczące tagów Tutaj:
przykład:
źródło
<<-
zostanie użyta, wiodąca karta nie zapobiegnie rozpoznaniu znacznikaPOSIX 7
cytowany kennytm
man bash
, ale większość z nich to także POSIX 7: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04 :Przykłady
Niektórych przykładów jeszcze nie podano.
Cytaty zapobiegają rozszerzaniu parametrów
Bez cytatów:
Wynik:
Z cytatami:
lub (brzydkie, ale ważne):
Wyjścia:
Łącznik usuwa wiodące karty
Bez łącznika:
gdzie
<tab>
jest dosłowna karta i można ją wstawić za pomocąCtrl + V <tab>
Wynik:
Z łącznikiem:
Wynik:
Jest to oczywiście po to, abyś mógł wciąć swój
cat
kod otaczający, który jest łatwiejszy do odczytania i utrzymania. Na przykład:Niestety nie działa to w przypadku znaków spacji: POSIX preferował
tab
tutaj wcięcia. Yikes.źródło
<<-
i<tab>a
należy zauważyć, że celem było umożliwienie normalnego wcięcia kodu w skrypcie, jednocześnie umożliwiając rozpoczęcie tekstu heredoc przedstawionego procesowi odbiorczemu w kolumnie 0. Nie jest to zbyt często spotykana funkcja i trochę więcej kontekstu może zapobiec$
"$a"'$b'"$c"
, ale tutaj nie ma analogii AFAIK.Używanie trójnika zamiast kota
Nie do końca jako odpowiedź na pierwotne pytanie, ale i tak chciałem się z tym podzielić: musiałem utworzyć plik konfiguracyjny w katalogu, który wymagałby uprawnień roota.
W tym przypadku nie działa:
ponieważ przekierowanie jest obsługiwane poza kontekstem sudo.
Zamiast tego użyłem tego:
źródło
Małe rozszerzenie powyższych odpowiedzi. Trailing
>
kieruje dane wejściowe do pliku, zastępując istniejącą zawartość. Jednak szczególnie wygodnym zastosowaniem jest>>
dołączona podwójna strzałka, która dodaje nową zawartość na końcu pliku, jak w:To wydłuża czas
fstab
bez martwienia się o przypadkową modyfikację dowolnej zawartości.źródło
To niekoniecznie jest odpowiedź na pierwotne pytanie, ale dzielenie się niektórymi wynikami z moich własnych testów. To:
utworzy ten sam plik co:
Nie widzę więc sensu używania polecenia cat.
źródło
<<test
bezcat <<test
.Warto zauważyć, że tutaj dokumenty działają również w pętlach bash. Ten przykład pokazuje, jak uzyskać listę kolumn tabeli:
lub nawet bez nowej linii
źródło