Para me lembrar quando tento usar shopt
em Zsh em vez de setopt
, criei o seguinte alias, testando-o primeiro em um prompt de shell:
$ alias shopt='echo "You\'re looking for setopt. This is Z shell, man, not Bash."'
Apesar da correspondência das aspas simples externas e das aspas duplas internas, e do apóstrofo sendo escapado, fui solicitado a terminar de fechar as aspas com:
dquote > _
O que está acontecendo?
Parecia que o escape estava sendo ignorado ou que precisava ser escapado duas vezes por causa de vários níveis de interpretação... Então, apenas para testar essa teoria, tentei escapar duas vezes (e escapar três vezes, e ligado) todo o caminho até:
alias shopt='echo "You\\\\\\\\\\\\\\\\\\\\\\'re looking for setopt. This is Z shell, man, not Bash." '
e nunca vi nenhum comportamento diferente. Isso não faz sentido para mim. Que tipo de voodoo estranho está impedindo o shell de se comportar como eu esperava?
A solução prática é não usar aspas para echo
, já que realmente não precisa de nenhuma, e usar aspas duplas para alias
, e escapar do apóstrofo para que seja ignorado quando o texto for echo
editado. Então todos os problemas práticos desaparecem.
Pode me ajudar? Eu preciso de resolução para este problema desconcertante.
Isso é
zsh
, cara, nãofish
.Em
zsh
, como em todo shell do tipo Bourne (e também emcsh
), as aspas simples são aspas fortes, não há como escapar dentro delas (exceto usando asrcquotes
opções sugeridas por @JdeBP, ondezsh
emularc
as aspas¹). Você não pode ter uma aspa simples dentro de uma string com aspas simples, você precisa primeiro fechar a string com aspas simples e inserir as aspas simples literais usando outro mecanismo de aspas (como\
ou"
):Ou:
Embora você também possa fazer:
(
"..."
são aspas mais fracas dentro das quais vários caracteres, inclusive\
(aqui usado para escapar do embutido"
) ainda são especiais).Ou:
(
$'...'
é ainda outro tipo de citação de ksh93, onde o'
pode ser escapado com\'
).(e BTW, você também pode usar o padrão
set -o
no lugar desetopt
inzsh
.bash
, por razões históricas, tem dois conjuntos de opções, um que você define comset -o
outro comshopt
;zsh
como a maioria dos outros shells, tem apenas um conjunto de opções).¹ Em
rc
, o shell do Plan9, com uma versão para unix-like também disponível, as aspas simples são o único mecanismo de aspas (barra invertida e aspas duplas são caracteres comuns ali), a única maneira de inserir uma aspa simples literal é com''
dentro aspas simples, então comzsh -o rcquotes
, você poderia fazer:Isso não é vodu. Esta é a citação normal do shell POSIX em ação. Não há mecanismo de escape dentro de strings com aspas simples . Eles sempre terminam na próxima aspa simples. Existe uma extensão do shell Z que faz com que duas strings sucessivas com aspas simples recebam uma aspa simples entre elas, que você pode empregar. Ou você pode simplesmente encerrar a string com aspas simples, usar uma aspa simples com escape (ou mesmo sem aspas simples) e, em seguida, iniciar uma segunda string com aspas simples.
Ou você não poderia usar contrações em suas mensagens. ☺
Leitura adicional
As outras respostas explicam bem por que você está vendo esse comportamento. Mas se eu puder fazer uma sugestão de como realmente resolver esse problema:
Não use pseudônimos para nada nem remotamente complicado.
Claro, você pode amarrar seu cérebro em nós tentando descobrir como aninhar N camadas de aspas, mas raramente vale a pena para um alias. Quando um alias é complicado o suficiente para que suas aspas se tornem não triviais, apenas mude para uma função shell:
Isso remove toda uma camada de aspas, permite que você adicione mais código à função shell posteriormente e geralmente é muito mais fácil de ler. Ele também permite um controle muito mais preciso sobre como e onde os argumentos são inseridos, em vez da abordagem de alias de "apenas substitua o início da linha e deixe as palavras restantes caírem onde puderem". Por exemplo, com seu alias (corrigido), se você digitar isto:
... então você obterá esta saída:
Provavelmente não é isso que você queria. A função shell consumirá todos os argumentos que você passar para ela e os descartará silenciosamente.
Nos dias em que você não quiser lutar contra as aspas, use outro caractere como Unicode U+2019 em vez de
'
apóstrofes.Pressione e segure Ctrl+ Shifte digite
u2019
e este caractere aparecerá’
(er... dependendo da sua localidade?).Tal uso de
’
(U+2019) está correto porque este caractere é oficialmente destinado a ser usado como apóstrofo. O padrão Unicode, versão 10.0 , recomenda explicitamente esse uso. O padrão reconhece que'
(U+0027) é comumente usado como apóstrofo devido à sua presença em ASCII e em teclados, e parece permitir isso. Mas então afirma que’
(U+2019) é o preferido para apóstrofos usados como pontuação (e dá uma contração como exemplo). Os únicos apóstrofos para os quais’
(U+2019) não são preferidos são aqueles usados como sinais diacríticos em vez de sinais de pontuação; esses são melhor escritosʼ
(U+02BC). De Apóstrofes (p. 276) na seção 6.2 do padrão:Um comentário agora excluído me deu uma dica e me deixou no meio do caminho para a resposta.
É impossível escapar de uma aspa simples dentro de uma string de aspas simples .
Essa limitação não está presente em strings com aspas duplas, pois certamente estou escapando de uma aspa simples dentro de uma string com aspas duplas em minha solução final: