web-dev-qa-db-fra.com

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

Je lis le tutoriel Shell aujourd'hui depuis 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é ça sur mon serveur centos, ça ne marche pas, un > invite à me suggérer 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’exclut, le ',
comment dois-je représenter un guillemet simple 'dans une phrase entre guillemets simples?

28
Zen

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 - Wiki de Greg

51
Mikel

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 cependant être échappé par une barre oblique inverse:

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

Vous pouvez utiliser:

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

Pour que Shell cite en toute sécurité 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.

1
mikeserv