Sei que isso provavelmente já foi solicitado antes, mas não consegui encontrá-lo no Google.
Dado
- Kernel do Linux
- Nenhuma configuração que altera $ HOME
- bater
Será ~ == $HOME
verdade?
bash
shell
environment-variables
home
PythonNut
fonte
fonte
~
que será equivalente a$HOME
qualquer ambiente POSIX; mas eu posso estar errado.echo "~"
eecho "$HOME"
.~
ou$HOME
. : P~
".) De qualquer forma, algo a ter em mente para o leitor casual, como eu.Respostas:
O que é importante entender é que a
~
expansão é um recurso do shell (de alguns shells), não é um personagem mágico do que significa o diretório inicial onde quer que seja usado.Ele é expandido (pelo shell, que é um aplicativo usado para interpretar linhas de comando), como
$var
é expandido para seu valor sob algumas condições, quando usado em uma linha de comando do shell antes que o comando seja executado.Esse recurso apareceu pela primeira vez no shell C no final da década de 1970 (o shell Bourne não o possuía, nem seu antecessor, o shell Thompson), mais tarde foi adicionado ao shell Korn (um shell mais novo construído sobre o shell Bourne no anos 80). Ele acabou sendo padronizado pelo POSIX e agora está disponível na maioria dos shells, incluindo os que não são do POSIX
fish
.Como ele é amplamente utilizado em shells, alguns aplicativos não-shell também o reconhecem como significando o diretório inicial. Esse é o caso de muitas aplicações em seus arquivos de configuração ou a sua própria linha de comando (
mutt
,slrn
,vim
...).bash
especificamente (que é o shell do projeto GNU e amplamente usado em muitos sistemas operacionais baseados em Linux), quando chamadosh
, segue principalmente as regras do POSIX sobre~
expansão, e em áreas não especificadas pelo POSIX, se comporta principalmente como o shell Korn (de que é um clone parcial).Embora
$var
seja expandido na maioria dos lugares (exceto dentro de aspas simples), a~
expansão, sendo uma reflexão tardia, é expandida apenas em algumas condições específicas.Ele é expandido quando por seu próprio argumento em contextos de lista, em contextos em que uma sequência é esperada.
Aqui estão alguns exemplos de onde é expandida
bash
:cmd arg ~ other arg
var=~
var=x:~:x
(exigido pelo POSIX, usado para variáveis comoPATH
,MANPATH
...)for i in ~
[[ ~ = text ]]
[[ text = ~ ]]
(a expansão de~
ser tomada como padrão na AT&T,ksh
mas nãobash
desde a versão 4.0).case ~ in ~) ...
${var#~}
(embora não em outras conchas)cmd foo=~
(embora não quando invocado comosh
e apenas quando o que está à esquerda da=
figura tiver o formato de umbash
nome de variável não citado )cmd ~/x
(exigido pelo POSIX obviamente)cmd ~:x
(mas nãox:~:x
oux-~-x
)a[~]=foo; echo "${a[~]} $((a[~]))"
(não em outras conchas)Aqui estão alguns exemplos em que não é expandido:
echo "~" '~'
echo ~@ ~~
(observe também que~u
se destina a expandir para o diretório inicial do usuáriou
).echo @~
(( HOME == ~ ))
,$(( var + ~ ))
extglob
:case $var in @(~|other))...
(emboracase $var in ~|other)
esteja OK)../configure --prefix=~
(como--prefix
não é um nome de variável válido)cmd "foo"=~
(embash
, por causa das aspas).sh
:export "foo"=~
,env JAVA_HOME=~ cmd
...Quanto ao que ele se expande:
~
expande sozinho para o conteúdo daHOME
variável, ou quando não está definido, para o diretório inicial do usuário atual no banco de dados da conta (como uma extensão, pois o POSIX deixa esse comportamento indefinido).Deve-se notar que no ksh88 e nas
bash
versões anteriores à 4.0, a expansão do til passou por globbing (geração de nome de arquivo) em contextos de lista:Isso não deve ser um problema em casos habituais.
Observe que, por ser expandido, o mesmo aviso se aplica a outras formas de expansão.
Não funciona se
$HOME
começa com-
ou contém..
componentes. Portanto, mesmo que seja pouco provável que faça alguma diferença, estritamente falando, deve-se escrever:Ou até:
(para cobrir valores de
$HOME
like-
,+2
...) ou simplesmente:(o
cd
leva ao seu diretório pessoal sem nenhum argumento)Outras conchas têm
~
expansões mais avançadas . Por exemplo, emzsh
, temos:~4
,~-
,~-2
(Com conclusão) usado para expandir os diretórios em sua pilha de diretórios (os lugares que vocêcd
para antes).~something
está sendo expandido.fonte
Em qualquer versão do Bash em qualquer sistema, sim .
~
como um termo por si só, é definido para expandir para:portanto, sempre será o mesmo que o que
$HOME
está no shell atual. Existem várias outras expansões de til, como~user
parauser
o diretório inicial de um arquivo, mas um único sem aspas~
sempre será expandido para"$HOME"
.Observe que o comportamento de
~
e$HOME
pode ser diferente em alguns casos: em particular, se$HOME
contiver espaços (ou outros caracteres IFS ),$HOME
(sem aspas) será expandido para várias palavras, enquanto~
é sempre uma única palavra.~
expande-se equivalentemente a"$HOME"
(entre aspas).Em relação à sua pergunta específica:
é sempre verdade, porque
[[
suprime a divisão de palavras.[[ ~ == $HOME ]
pode não ser seHOME
possui caracteres de correspondência de padrão , mas[[ ~ == "$HOME" ]]
(ou seja, citado"$HOME"
) é sempre verdadeiro. Usá-lo entre colchetes simples pode ser um erro de sintaxe para valores deHOME
espaços ou caracteres especiais. Para qualquer configuração diretório home sensata~
e"$HOME"
são os mesmos e são considerados iguais.Stéphane Chazelas observou um caso nos comentários onde
~
e$HOME
dão valores diferentes: se vocêunset HOME
, em seguida, quando você usa~
Bash vai chamargetpwuid
para ler um valor do banco de dados senha. Este caso é excluído por sua condição de não haver alteração na configuração$HOME
, mas vou mencioná-lo aqui por completo.fonte
/bin/sh
pode não serbash
. Não tenho certeza de que ash
especificação Posix fala sobre~
~
.~
não estava na casca de Thomson ou Bourne (que na época estavam disponíveis como/bin/sh
). Não é emrc
ou seus derivados (onde é usado para outra coisa)bash
, incluindo , seHOME
não estiver definido, se~
expande para o diretório inicial do usuário a partir do banco de dados passwd. Portanto, esse é um caso em que~
pode não se expandir para o valor de$HOME
.bash
antes do bash4 era usado globbing na expansão de til (tentativaHOME='/*' bash -c 'echo /*'
). EntãoHOME=/*; [ "$HOME" = ~ ]
, retornaria um erro lá.get_current_user_info
, que usagetpwuid
em todas as plataformas, exceto Tandem .