Różnica między echo -e „<ciąg>” i echo $ „<ciąg>”

20

Jaka jest różnica między używaniem

echo -e "Hello\nWorld" 

i

echo $"Hello\nWorld" 

czy nie oba generują:

Hello
World
znak
źródło
1
Próbowałeś? Drugi wychodzi Hello\nWorld. Potrzebujesz -eprzełącznika, aby interpretować znaki specjalne.
becko
4
W przypadku drugiego podejrzewam, że chciałeś napisać go pojedynczymi cudzysłowami echo $'Hello\nWorld', które zostaną wydrukowane w dwóch wierszach pod bash.
John1024
@becko, tak, wypróbowałem to i oba generują dokładnie to samo.
Mark

Odpowiedzi:

33

echo -ei echo $'...'oba są podobne, ponieważ obsługują następujące sekwencje specjalne:

  \a     alert (bell)
  \b     backspace
  \e
  \E     an escape character
  \f     form feed
  \n     new line
  \r     carriage return
  \t     horizontal tab
  \v     vertical tab
  \\     backslash
  \0nnn  the eight-bit character whose value is the octal value nnn (zero to three octal digits)
  \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
  \uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
  \UHHHHHHHH
         the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)

Mają różnice. Oprócz powyższych echo -eobsługuje:

  \c     suppress further output
  \0nnn  the eight-bit character whose value is the octal value nnn (zero to three octal digits)

Natomiast $'....'obsługuje:

 \'     single quote
 \"     double quote
 \nnn   the eight-bit character whose value is the octal value nnn (one to three digits)
 \cx    a control-x character

Zauważ, że między nimi \crozszerzenia są niezgodne:

$ echo -e  'start\n\cIstop'
start
$ echo  $'start\n\cIstop'
start
        stop

W echo -epowyższym przypadku \cpomija dalsze dane wyjściowe, ignorując w ten sposób Istop. W przeciwieństwie do $'...'The \cIinterpretowany jest jako zakładka.

Forma podobna wizualnie: $"..."

W przeciwieństwie do $'...', funkcja $"..."jest zupełnie inna. Spowoduje to przetłumaczenie zawartego w nim ciągu zgodnie z bieżącymi ustawieniami narodowymi.

echo -ekontrowersje

echo -enie jest powszechnie obsługiwany przez powłoki i wielu uważa tę -eopcję za błąd projektowy. Przestrzegać:

$ ls
-e  -n
$ echo *
$ printf "%s\n" *
-e
-n

Jak widać, jeśli to, co drukujesz, echozaczyna się od myślnika, wyniki mogą być nieoczekiwane. O ile nie masz pewności, że pierwszy ciąg, który będziesz drukować echo, nie zaczyna się od myślnika, prawdopodobnie lepiej będzie użyć printf.

Z tych powodów standard POSIX stwierdza :

Nowe aplikacje są zachęcane do używania printf zamiast echa.

Chet Ramey, który utrzymuje bashod 22 lat, zgadza się :

Kod [N] ew powinien używać printf.

John1024
źródło
1
Warto również zauważyć, że zarówno Chet, jak i POSIX zalecają używanie printfzamiastecho
geirha
@geirha Bardzo dobre punkty. Odpowiedź zaktualizowana.
John1024
1
Problem nieoczekiwanych opcji z globów (jak *) nie jest właściwie specyficzny echo. Dzieje się tak z każdym poleceniem, które rozpoznaje krótkie lub długie opcje (napisane w tradycyjny sposób) i pobiera operandy nazw plików, w tymls . Prawdopodobnie sytuacja jest nieco gorsza, echoponieważ (jak wspomina twoje źródło) echozazwyczaj nie akceptuje --wskazania końca opcji, podczas gdy można pisać polecenia takie jak ls -- *l. (I tak naprawdę zwykle należy tak pisać polecenia, używając globów rozpoczynających się od *lub -, zwłaszcza w skryptach).
Eliah Kagan
Dziękuję za dokładną odpowiedź, mam płacił za moje Systemy operacyjne i oczywiście musiałem wydrukować jakiś tekst za pomocą \nsekwencji ucieczki, więc w rzeczywistości nie ma znaczenia, czy mogę używać echo -e '...', echo $'...'lubecho $"..."
Mark