Comment faire écho à "guillemet simple" lors de l'utilisation de guillemet simple pour encapsuler des caractères spéciaux dans le shell?

26

Je lis aujourd'hui un didacticiel sur le shell à partir de http://www.tutorialspoint.com/unix/unix-quoting-mechanisms.htm

Dans lequel il mentionne:

Si un seul guillemet apparaît dans une chaîne à afficher, vous ne devez pas placer la chaîne entière entre guillemets simples, au lieu de cela, vous devez précéder cette utilisation d'une barre oblique inverse () comme suit:

echo 'It\'s Shell Programming'

J'ai essayé cela sur mon serveur centos, cela ne fonctionne pas, un message me >demande de taper plus.

Je me demandais, puisque deux guillemets simples transforment tous les caractères spéciaux en caractères normaux, qui incluent le symbole d'échappement \, mais s'excluent eux-mêmes, le ',
comment dois-je représenter une seule guillemet simple 'dans une phrase entre guillemets simples?

Zen
la source
1
Pourquoi ne pas utiliser echo It\'s Shell Programmingou echo "It's Shell Programming"?
cuonglm
@cuonglm, car je peux utiliser une phrase commeecho Wow, I'm going to have lots of $$$$$$ now
Zen
2
Vous devez donc utiliser des guillemets doubles et échapper $également. Quelque chose comme echo Wow, I\'m going to have lots of \$\$\$\$\$\$ nowou justeecho Wow, I\'m going to have lots of '$$$$$$' now
cuonglm
@cuonglm, oui, je peux le faire et je sais comment je peux le faire. Mais le tutoriel que j'ai lu semble confiant qu'il existe un moyen d'échapper aux guillemets simples à l'intérieur de phrases entre guillemets simples, mais l'exemple donné du tutoriel ne fonctionne pas. Je me demande donc si quelqu'un connaît la solution.
Zen
1
Que dis-tu de ça? echo 'It'"'"'s Shell Programming'. Je le divise simplement en 3 chaînes, la première et la dernière entourées de guillemets simples, mais celle du milieu a une guillemet simple entourée de guillemets doubles.
jcbermu

Réponses:

49

Le tutoriel est faux.

POSIX dit:

Un guillemet simple ne peut pas se produire entre guillemets simples.

Voici quelques alternatives:

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

Pour en savoir plus: Citations - Greg's Wiki

Mikel
la source
4
Un de plus: echo 'It''s Shell Programming'- zsh avec rc_quotesjeu d'options (et le shell rc aussi) - une paire de guillemets simples à l'intérieur de guillemets simples représente un seul guillemet simple.
Michał Politowski
5
J'utilise parfois q="'"et qq='"'pour faire ce nettoyant. Cela permet alors echo "It${q}s ${qq}Shell Programming${qq}"(des accolades sont nécessaires étant donné les lettres de fin). Sécurité POSIX. La couche externe doit être placée entre deux guillemets.
Adam Katz
1

Vous pouvez utiliser:

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

Pour shell en toute sécurité citer une ligne de valeur par ligne.

En fonction du shell, vous pouvez également avoir la possibilité de faire:

printf %q\\n "$arbitrary_value"

Bien que je préfère généralement faire:

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

Une approche plus manuelle pourrait ressembler à:

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

... qui est, au moins, sans fourche.

mikeserv
la source
1
Je n'ai absolument aucune idée de ce dont vous parlez, sauf la phrase printf %q\\n "$arbitrary_value", d'autres sont trop compliqués.
Zen
1

Au cas où quelqu'un d'autre viendrait pour mettre un mélange de guillemets simples et doubles dans un fichier, cela fonctionne aussi:

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__

Tout ce que le shell peut voir comme une variable doit être échappé par une barre oblique inverse:

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