Isso não está relacionado a citar, mas sim ao processamento de argumentos.
Considere o exemplo arriscado:
find -exec sh -c "something {}" \;
-
Isso é analisado pelo shell e dividido em seis palavras:
find,-exec,sh,-c,something {}(sem citações mais),;. Não há nada para expandir. O shell executafindcom essas seis palavras como argumentos. -
Quando
findencontra algo para processar, digamosfoo; rm -rf $HOME, substitui{}porfoo; rm -rf $HOMEe executashcom os argumentossh,-cesomething foo; rm -rf $HOME. -
shagora vê-ce, como resultado, analisasomething foo; rm -rf $HOME( o primeiro argumento não opcional ) e executa o resultado.
Agora, considere a variante mais segura:
find -exec sh -c 'something "$@"' sh {} \;
-
O shell executa
findcom os argumentosfind,-exec,sh,-c,something "$@",sh,{},;. -
Agora, quando
findencontrafoo; rm -rf $HOME, substitui{}novamente e executashcom os argumentossh,-c,something "$@",sh,foo; rm -rf $HOME. -
shvê-ce analisasomething "$@"como o comando a ser executado eshefoo; rm -rf $HOMEcomo os parâmetros posicionais ( iniciando em$0), expande"$@"parafoo; rm -rf $HOMEcomo um único valor e executasomethingcom o único argumentofoo; rm -rf $HOME.
Você pode ver isso usando printf . Crie um novo diretório, digite-o e execute
touch "hello; echo pwned"
Executando a primeira variante da seguinte forma
find -exec sh -c "printf \"Argument: %s\n\" {}" \;
produz
Argument: .
Argument: ./hello
pwned
enquanto a segunda variante é executada como
find -exec sh -c 'printf "Argument: %s\n" "$@"' sh {} \;
produz
Argument: .
Argument: ./hello; echo pwned