Digamos:
xb@dnxb:/tmp$ echo 'ls -l /proc/$$/fd | grep a.sh' > a.sh; \
> while IFS='' read -r f; do \
> echo "$f"; "$f" a.sh; \
> done < <(tail -n +2 /etc/shells)
/bin/sh
lr-x------ 1 xiaobai xiaobai 64 Jan 20 00:09 10 -> /tmp/a.sh
/bin/dash
lr-x------ 1 xiaobai xiaobai 64 Jan 20 00:09 10 -> /tmp/a.sh
/bin/bash
lr-x------ 1 xiaobai xiaobai 64 Jan 20 00:09 255 -> /tmp/a.sh
/bin/rbash
lr-x------ 1 xiaobai xiaobai 64 Jan 20 00:09 255 -> /tmp/a.sh
/bin/zsh
lr-x------ 1 xiaobai xiaobai 64 Jan 20 00:09 11 -> /tmp/a.sh
/usr/bin/zsh
lr-x------ 1 xiaobai xiaobai 64 Jan 20 00:09 11 -> /tmp/a.sh
/bin/ksh93
lr-x------ 1 xiaobai xiaobai 64 Jan 20 00:09 10 -> /tmp/a.sh
/bin/rksh93
lr-x------ 1 xiaobai xiaobai 64 Jan 20 00:09 10 -> /tmp/a.sh
xb@dnxb:/tmp$
O bash sempre fixou o número fd 255 e o zsh fixou o número fd 11 por padrão?
Eu faço esta pergunta porque preciso extrair o caminho completo executado de qualquer processo shell. Eu me pergunto se posso codificar meu script para referir esses números fixos ou não.
Observe que isso é para script pessoal e não significa executar em negócios críticos, então não estou procurando 100% confiável, mas o número fd é fixo na maioria dos casos ?
[ATUALIZAR]:
A razão pela qual eu não analiso o cmdline
é porque:
xb@dnxb:~/Downloads$ cat foo.sh
#!/bin/bash
cat "/proc/$$/cmdline" | tr '\0' '\n'
readlink -f /proc/$$/fd/255
xb@dnxb:~/Downloads$ bash --norc foo.sh --norc
bash
--norc
foo.sh
--norc
/home/xiaobai/Downloads/foo.sh
xb@dnxb:~/Downloads$
Como você pode ver, só é fd
possível fornecer o caminho completo /home/xiaobai/Downloads/foo.sh
, mas não o arquivo cmdline
. E o script não pode distinguir foo.sh
ou --norc
é um caminho ou uma opção, pois foo.sh
pode aparecer em qualquer posição de opção, a menos que eu faça uma verificação feia, como não começa com --
.
Embora fd
não tenha nenhum problema em produzir o caminho completo correto, mesmo eu bash --norc foo.sh --norc foo2.sh
.
De qualquer forma, acabei de perceber que minha tarefa não precisa verificar isso, pois notei que nenhum processo do sistema, exceto o processo personalizado, é herdado do shell. Mas ainda qualquer resposta ajudará o futuro leitor.
A única coisa que você pode ter certeza é que não serão fds 1 a 9, pois esses são reservados para uso do usuário em implementações POSIX sh e 0 pode ser usado no
sh < your-script
caso. yash o estende para fds 1 a 99.Você não pode confiar que seja um valor fixo, pois o shell usará um valor diferente se o fd já estiver aberto na inicialização. A maioria dos shells parece usar os primeiros fds livres acima de 9 (ou 99 para yash) para seus fds internos.
bash
parece estar usando 255 e diminuindo em vez de subir quando não pode usá-lo:Usar
$0
para obter o caminho do script que está sendo executado geralmente é a melhor abordagem. Veja também: $0 sempre incluirá o caminho para o script?Expandindo meu comentário acima, você pode usar
/proc/<pid>/cmdline
para obter as informações nas quais está interessado. Observe que os tokens são delimitados por caracteres NIL, então você terá que processar um pouco a saída:Então, se por exemplo eu tiver:
Aqui estão alguns exemplos de execuções:
Observe que isso nem sempre fornece o caminho completo para o binário. Para isso, você pode olhar para
/proc/<pid/exe
:Isso pode não ser o que você está procurando, eu simplesmente não entendo como olhar para os descritores de arquivos abertos vai lhe dar o que você quer.