Co oznacza `(backquote / backtick) w poleceniach?

159

Natrafiłem na następujące polecenie:

sudo chown `id -u` /somedir

i zastanawiam się: jakie jest znaczenie tego `symbolu. Zauważyłem na przykład, że chociaż powyższe polecenie działa dobrze, poniższe poniżej nie działa:

sudo chown 'id -u' /somedir
gws
źródło

Odpowiedzi:

199

To jest backtick . Strzałka wsteczna nie jest znakiem cudzysłowu. Ma to bardzo szczególne znaczenie. Wszystko, co wpisujesz między backtickami, jest analizowane (wykonywane) przez powłokę przed głównym poleceniem (jak chownw twoich przykładach), a dane wyjściowe z tego wykonania są używane przez to polecenie, tak jakbyś wpisał to wyjście w tym miejscu w wiersz poleceń.

Więc co

sudo chown `id -u` /somedir

skutecznie działa (w zależności od identyfikatora użytkownika ) to:

sudo chown 1000 /somedir
  \    \     \     \
   \    \     \     `-- the second argument to "chown" (target directory)
    \    \     `-- your user ID, which is the output of "id -u" command
     \    `-- "chown" command (change ownership of file/directory)
      `-- the "run as root" command; everything after this is run with root privileges

Spójrz na to pytanie, aby dowiedzieć się, dlaczego w wielu sytuacjach nie jest dobrym pomysłem stosowanie back -icksów.

Przy okazji, jeśli kiedykolwiek chciałeś użyć dosunięcia dosłownie, np. W ciągu, możesz uciec od niego, umieszczając \przed nim odwrotny ukośnik ( ).

rozcietrzewiacz
źródło
36
To dość dobrze wyjaśnia backtyki, ale użycie $(your expression)jest lepszym sposobem na zrobienie tego samego, co $()pozwala zagnieżdżać wyrażenia. na przykład: cd $(dirname $(type -P touch))przeniesie cię do katalogu zawierającego touchkomendę
Khaja Minhajuddin
11
@KhajaMinhajuddin Zdecydowanie masz rację co do zagnieżdżania - powyższe pytanie szczegółowo to opisuje. Ale chociaż uważam, że jest to dobra praktyka $()w większości sytuacji, nie robi to gorszych zwrotów. Ze względów praktycznych trzeba przyznać, że pisanie w wierszu poleceń jest znacznie szybsze (2 naciśnięcia klawiszy w porównaniu do co najmniej 5, w tym Shift).
rozcietrzewiacz
2
@rozcietrzewiacz Twoja ostatnia uwaga jest prawdopodobnie prawdą dla większości klawiatur, ale $( )zdecydowanie łatwiej ją pisać niż ` `przynajmniej na klawiaturze francuskiej.
jlliagre
1
@KhajaMinhajuddin Możesz zagnieżdżać backticks, ale musisz uciec z 2. poziomu backticks, a 2. poziom nesting potrzebujesz 3 backticks, 3. poziom nesting 5 backticks, 4. poziom 7, i c.
Justin CB,
66

Chciałbym tu dodać jeszcze kilka punktów.

Strzałka wsteczna `…`nazywana jest w rzeczywistości zastępowaniem poleceń . Podstawienie polecenia polega na ocenie polecenia umieszczonego w backstick i dostarczeniu jego wyniku jako argumentu do rzeczywistego polecenia.

Podstawienie polecenia można wykonać na dwa sposoby, z których jeden jest używany, $(…)a drugi jest `…`. Oba działają tak samo, ale $(…)forma jest nowoczesna i ma większą przejrzystość i czytelność.

A więc

sudo chown $(id -u) /somedir

mogą być preferowane nad innymi.

I jeszcze jedna rzecz, na którą należy zwrócić uwagę, to relacja zastępowania poleceń z regułami cytowania bash, jak wspomniano w dokumencie bash .

Jeśli podstawienie pojawia się w podwójnych cudzysłowach, dzielenie słów i rozwijanie nazw plików nie są wykonywane w wynikach.

Kannan Mohan
źródło
8
Również $(...)gniazduje lepiej.
Kusalananda
$()i "``"nie działają w ten sam sposób
Kun
10

Jedna uwaga wyjaśnienia rzadko obejmuje:

Backticks (czasami nazywany także Graves, ponieważ podwaja się jako wspólny akcent w języku francuskim i innych językach) zastępują tylko Standardowy Wyjście , ale nie Standardowy Błąd.

Kontynuując poprzedni przykład:

file `which hostname`

będzie działać zgodnie z oczekiwaniami, ale w:

file `which hostnameX`

whichzwróci błąd, a dane wyjściowe zostaną zastąpione błędem standardowym, zamiast zastępowania w wierszu poleceń obok file; w ogóle nie będzie standardowego wyjścia, które można potwierdzić, uruchamiając:

which hostnameX

which hostnameX 2>/dev/null

W tym przypadku,

file `which hostnameX` 

wyświetli dwa komunikaty o błędach (pierwszy z powodu, which hostnameXa drugi zaraz po poprzednim z powodu samego pliku, w którym wykryto brak nazwy pliku, a więc całe polecenie

zmniejszy się zasadniczo do:

file

co oczywiście jest złym użytkowaniem i zwróci błąd użytkowania.

(jeśli chcesz to sprawdzić samodzielnie, możesz spróbować:

file `which hostnameX 2>/dev/null`    # just the file-command bad-usage error msg is printed

file `which hostnameX 2>/dev/null` 2>/dev/null  # now nothing is printed on the screen :)
Dave K.
źródło
4

Backtick `uruchamia zawartość dołączonego ciągu, więc coś takiego

file `which hostname`

znajdzie ścieżkę do komendy hostname, a następnie powie ci, jak została zbudowana.

Polecenie wprowadzone w pytaniu uruchamia się, id -uaby uzyskać efektywny identyfikator użytkownika, a następnie zmienia własność / somedir na tego użytkownika.

juliański
źródło
2

Ten symbol oznacza, że ​​cokolwiek w nim jest interpretowane jako wynik tego polecenia.

na przykład:

$ls /home
one two
$pwd
/usr/three
$cp `pwd` /home
$ls /home
one two three

Powyższe powoduje threeskopiowanie /homekatalogu do mojego katalogu.

Hanan N.
źródło
1

Cofnięcia przypominają podstawianie poleceń. Ta składnia backticks jest archaiczna i wiem, znak dolara z dwóch nawias jest wspólne: $().

Co to jest zastępowanie poleceń?

Podstawienie polecenia jest pojedynczą operacją ze specjalną składnią, która służy zarówno do wykonania polecenia, jak i do zapisania jego wyniku w zmiennej do późniejszego użycia.

Przykład z datą:

thedate=$(date)

Możemy wtedy wydrukować wynik: „Data to% s \ n” „$ thedate”.

  1. Składnia podstawiania poleceń to $().
  2. Samo polecenie to date.
  3. Łącząc oba otrzymujemy, $(date)którego wynikiem jest podstawienie.
  4. Wyświetlamy wartość wyjściową zatrzymaną przez zmienną za pomocą printf, zgodnie z powyższym poleceniem.
użytkownik9303970
źródło