O que $$ significa no shell?

143

Certa vez, li que uma maneira de obter um nome de arquivo exclusivo em um shell para arquivos temporários era usar um cifrão duplo ( $$). Isso produz um número que varia de tempos em tempos ... mas se você chamá-lo repetidamente, ele retorna o mesmo número. (A solução é usar apenas o tempo.)

Estou curioso para saber o que $$realmente é e por que isso seria sugerido como uma maneira de gerar nomes de arquivos exclusivos.

gatinha
fonte

Respostas:

102

No Bash $$está o ID do processo, conforme observado nos comentários, não é seguro usá-lo como um nome de arquivo temporário por vários motivos.

Para nomes de arquivos temporários, use o mktempcomando

Joe Skora
fonte
35
Para as pessoas que apenas olham para a resposta superior, $$ não é bom para um único arquivo se estiver gravando em um diretório publicamente gravável (por exemplo, / tmp). É fácil jogar lixo / tmp com links simbólicos que farão com que seu script escreva em algum lugar indesejável. O mktemp é muito melhor.
Chris Jester-Young
4
Sim, usar $$ causará uma brecha de segurança desagradável. Não faça isso.
emk 17/09/08
7
Ou a pessoa que fez a pergunta deve definir a resposta nominal superior abaixo como a resposta aceita ...
jtimberman
6
Eu adiciono "dólar dólar" para SEO.
Antoine
1
Se $$ apenas produz o pid, como pode ser "não seguro"? A brecha de segurança é criada em virtude do design inadequado, e não do PID no nome do arquivo tmp ... Se você se preocupa com a integridade da saída que vai tanto ao tmp, talvez você não deva colocá-lo lá em primeiro lugar? $$ não causará brecha na segurança, falta de previsão
niken
113

$$é o ID do processo (PID) no bash. Usar $$é uma péssima idéia, pois geralmente cria uma condição de corrida e permite que seu script de shell seja subvertido por um invasor. Veja, por exemplo, todas essas pessoas que criaram arquivos temporários inseguros e tiveram que emitir avisos de segurança.

Em vez disso, use mktemp. A página de manual do Linux para mktemp é excelente. Aqui está um exemplo de código:

tempfoo=`basename $0`
TMPFILE=`mktemp -t ${tempfoo}` || exit 1
echo "program output" >> $TMPFILE
emk
fonte
3
Obrigado. A mktempopção -tagora está obsoleta (acho que por causa de problemas com o char -). Use mktemp ${tempfoo}.XXXXXXestes dias . Tomo a liberdade de atualizar sua postagem.
Sebastian
1
Observe também que o backtick foi preterido ; portanto, use-o TMPFILE=$(mktemp).
Michael Kopp
20

$$ é o ID do processo atual.

pedra
fonte
7

Todo processo em um sistema operacional semelhante ao UNIX possui um identificador exclusivo (temporariamente), o PID. Dois processos em execução ao mesmo tempo não podem ter o mesmo PID, e $$ refere-se ao PID da instância do bash que está executando o script.

Isso é muito não é um identificador único, no sentido de que nunca será reutilizado (na verdade, os PIDs são reutilizados constantemente). O que ele fornece é um número tal que, se outra pessoa executar seu script, eles obterão um identificador diferente enquanto o seu ainda estiver em execução. Depois que o seu morre, o PID pode ser reciclado e outra pessoa pode executar seu script, obter o mesmo PID e o mesmo nome de arquivo.

Como tal, é realmente sensato dizer "$$ fornece um nome de arquivo de tal forma que, se alguém executar o mesmo script em que minha instância ainda está em execução, eles obterão um nome diferente".

Adam Wright
fonte
5

$$ é o seu PID. Realmente não gera um nome de arquivo exclusivo, a menos que você tenha cuidado e ninguém mais faça exatamente da mesma maneira.

Normalmente você criaria algo como / tmp / myprogramname $$

Existem muitas maneiras de resolver isso, e se você está escrevendo para locais em que outras pessoas podem escrever, não é muito difícil em muitos sistemas operacionais prever o PID que você terá e se esquivar - imagine que você está executando como root e eu crio / tmp / yourprogname13395 como um link simbólico apontando para / etc / passwd - e você escreve nele.

Isso é algo ruim de se fazer em um script de shell. Se você pretende usar um arquivo temporário para algo, deve usar um idioma melhor que permita pelo menos adicionar o sinalizador "exclusivo" para abrir (criar) o arquivo. Então você pode ter certeza de que não está subestimando outra coisa.

JBB
fonte
3

$$ é o pid do processo atual do shell. Não é uma boa maneira de gerar nomes de arquivos exclusivos.

leif
fonte
3

$$ é o pid (identificação do processo) do interpretador de shell executando seu script. É diferente para cada processo em execução em um sistema no momento, mas com o tempo o pid se espalha, e depois que você sai, haverá outro processo com o mesmo pid eventualmente. Enquanto você estiver executando, o pid é exclusivo para você.

A partir da definição acima, deve ser óbvio que, não importa quantas vezes você use $$ em um script, ele retornará o mesmo número.

Você pode usar, por exemplo, /tmp/myscript.scratch.$$ como seu arquivo temporário para itens que não precisam ser extremamente confiáveis ​​ou seguros. É uma boa prática excluir esses arquivos temporários no final do seu script, usando, por exemplo, o comando trap:

trap "echo 'Cleanup in progress'; rm -r $TMP_DIR" EXIT

fonte
2

É o ID do processo do bash. Nenhum processo simultâneo terá o mesmo PID.


fonte
2

O $$ é o ID do processo do shell no qual seu script está sendo executado. Para mais detalhes, consulte a página de manual do sh ou bash. As páginas do manual podem ser encontradas usando a linha de comando "man sh" ou pesquisando na web "shell manpage"

Shannon Nelson
fonte
2

Deixe-me segunda resposta da EMK - não use $$ por si só como algo "único". Para arquivos, use mktemp. Para outros IDs no mesmo script bash, use "$$$ (data +% s% N)" para ter uma chance razoavelmente boa de exclusividade.

 -k
Kevin Little
fonte
0

Além disso, você pode obter o nome de usuário de login através deste comando. Por exemplo.

echo $(</proc/$$/login id). After that, you need to use getent command.
Obivan
fonte