Jak powtórzyć „pojedynczy cytat”, gdy używasz pojedynczego cudzysłowu do zawijania znaków specjalnych w powłoce?


26

Czytam dzisiaj samouczek powłoki z http://www.tutorialspoint.com/unix/unix-quoting-mechanisms.htm

W którym wspomina:

Jeśli pojedynczy ciąg znaków pojawia się w ciągu, który ma być wyprowadzony, nie należy umieszczać całego ciągu w obrębie pojedynczych cudzysłowów, zamiast tego należy poprzedzić to odwrotnym ukośnikiem ():

echo 'It\'s Shell Programming'

Próbowałem tego na moim serwerze Centos, to nie działa, pojawia się >monit o wskazanie więcej.

Zastanawiałem się, ponieważ dwa pojedyncze cytaty przekształcić co w normalnych znaków specjalnych znaków, które obejmują symbol ucieczki \, ale wykluczyć sobie, ',
jak mam reprezentować pojedynczy apostrof 'w jednym cytowanym zdaniu?


1
Dlaczego nie użyć echo It\'s Shell Programminglub echo "It's Shell Programming"?
cuonglm

@cuonglm, ponieważ mogę użyć frazy typuecho Wow, I'm going to have lots of $$$$$$ now
Zen

2
Więc powinieneś użyć podwójnych cudzysłowów i uciec $. Coś jak echo Wow, I\'m going to have lots of \$\$\$\$\$\$ nowlub po prostuecho Wow, I\'m going to have lots of '$$$$$$' now
cuonglm

@cuonglm, tak, mogę to zrobić i wiem, jak to zrobić. Ale samouczek, który czytam, wydaje się być pewien, że istnieje sposób na uniknięcie pojedynczego cudzysłowu w wyrażeniach pojedynczych, ale podany przykład samouczka nie działa. Zastanawiam się więc, czy ktoś może znać rozwiązanie.
Zen

1
Co powiesz na to? echo 'It'"'"'s Shell Programming'. Po prostu dzielę to na 3 ciągi, pierwszy i ostatni otoczony pojedynczymi cudzysłowami, ale środkowy ma pojedynczy cytat otoczony podwójnymi cudzysłowami.
jcbermu

Odpowiedzi:


49

Samouczek jest nieprawidłowy.

POSIX mówi:

Pojedynczy cytat nie może wystąpić w pojedynczym cudzysłowie.

Oto kilka alternatyw:

echo $'It\'s Shell Programming'  # ksh, bash, and zsh only, does not expand variables
echo "It's Shell Programming"   # all shells, expands variables
echo 'It'\''s Shell Programming' # all shells, single quote is outside the quotes
echo 'It'"'"'s Shell Programming' # all shells, single quote is inside double quotes

Dalsza lektura: Cytaty - Wiki Grega


4
Jeszcze jedno: echo 'It''s Shell Programming'- zsh z rc_quoteszestawem opcji (i również powłoką rc) - para pojedynczych cudzysłowów w pojedynczych cudzysłowach reprezentuje pojedynczy pojedynczy cudzysłów.
Michał Politowski,

5
Czasami używam q="'"i qq='"'aby zrobić to czystsze. To następnie pozwala echo "It${q}s ${qq}Shell Programming${qq}"(nawiasy klamrowe są potrzebne, biorąc pod uwagę końcowe litery). Bezpieczny dla POSIX. Warstwa zewnętrzna musi być podwójnie cytowana.
Adam Katz

1

Możesz użyć:

sed "s/'"'/&\\&&/g
     s/.*/'"'&'"'/
' <<IN
$arbitrary_value
IN

Aby bezpiecznie shell podać cytowaną linię wartości na linię.

W zależności od powłoki możesz również mieć opcję:

printf %q\\n "$arbitrary_value"

Chociaż zwykle wolę robić:

a=$(alias "a=$arbitrary_value" a); a=${a#*=}

Bardziej ręczne podejście może wyglądać następująco:

sq(){ set \' "$1"
      while case $2 in (*\'*) :;;
      (*) ! RETURN="$1$2'"     ;;esac
      do  set "$1${2%%\'*}'\''" "${2#*\'}"
      done
}

... co najmniej bez widelca.


1
Zupełnie nie mam pojęcia o czym mówisz, z wyjątkiem frazy printf %q\\n "$arbitrary_value": inne są zbyt skomplikowane.
Zen

1

W przypadku, gdy ktoś przychodzi, aby umieścić w pliku mieszankę pojedynczych i podwójnych cudzysłowów, to też działa:

cat > its-shell-programing.txt << __EOF__
echo $'It\'s Shell Programming'
echo "It's Shell Programming"
echo 'It'\''s Shell Programming'
echo 'It'"'"'s Shell Programming'
__EOF__

Wszystko, co powłoka może postrzegać jako zmienną, musi być poprzedzone ukośnikiem odwrotnym:

cat >> its-shell-programing.txt << __EOF__
echo \$It\'s Shell Programming
__EOF__
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.