Eu tenho um script no qual não quero que ele chame exit
se estiver sendo originado.
Pensei em verificar se, $0 == bash
mas isso tem problemas, se o script é originário de outro script ou se o usuário o origina de um shell diferente, como ksh
.
Existe uma maneira confiável de detectar se um script está sendo originado?
Respostas:
Isso parece ser portátil entre Bash e Korn:
Uma linha semelhante a esta ou uma tarefa como
pathname="$_"
(com um teste e ação posteriores) deve estar na primeira linha do script ou na linha após o shebang (que, se usado, deve ser para ksh para que ele funcione sob mais circunstâncias).fonte
BASH_ENV
,$_
na parte superior do script será executado o último comandoBASH_ENV
.$_
é um problema.bash script
(invocação via executável do shell, que esta solução relata incorretamente como originada ) e (b) (muito menos provável)echo bash; . script
(se$_
coincidir com a origem do shell do script, esta solução a denuncia incorretamente como um subshell ). Somente variáveis especiais específicas do shell (por exemplo,$BASH_SOURCE
) permitem soluções robustas (segue-se que não há uma solução robusta compatível com POSIX). Ele é possível, embora pesado, para elaborar um teste cross-shell robusta.Se sua versão do Bash souber da variável de matriz BASH_SOURCE, tente algo como:
fonte
${BASH_SOURCE[0]}
vez de apenas$BASH_SOURCE
? E${0}
vs$0
?BASH_SOURCE
é uma variável de matriz (consulte o manual ) que contém um rastreamento de pilha de fontes, onde${BASH_SOURCE[0]}
é a mais recente. Os colchetes são usados aqui para dizer ao bash o que faz parte do nome da variável. Eles não são necessários$0
neste caso, mas também não machucam. ;)$array
, obtém${array[0]}
por padrão. Então, novamente, há uma razão [...]?Soluções robustas para
bash
,ksh
,zsh
, incluindo uma cruz-concha uma, além de uma solução compatível com POSIX razoavelmente robustas :Os números de versão fornecidos são aqueles em que a funcionalidade foi verificada - provavelmente, essas soluções também funcionam em versões muito anteriores - bem-vindo feedback .
Usando apenas recursos POSIX (como in
dash
, que atua como/bin/sh
Ubuntu), não há uma maneira robusta de determinar se um script está sendo originado - veja abaixo a melhor aproximação .Seguidores de uma linha seguem - explicação abaixo; a versão cross-shell é complexa, mas deve funcionar robusta:
bash (verificado em 3.57 e 4.4.19)
ksh (verificado em 93u +)
zsh (verificado em 5.0.5) - certifique-se de chamar isso fora de uma função
shell cruzado (bash, ksh, zsh)
Compatível com POSIX ; não é uma linha (tubulação única) por razões técnicas e não é totalmente robusta (veja abaixo):
Explicação:
festança
Nota: A técnica foi adaptada da resposta do usuário5754163 , pois se mostrou mais robusta que a solução original,
[[ $0 != "$BASH_SOURCE" ]] && sourced=1 || sourced=0
[1]O Bash permite
return
instruções apenas de funções e, no escopo de nível superior de um script, somente se o script for originado .return
for usado no escopo de nível superior de um script não originado , uma mensagem de erro será emitida e o código de saída será definido como1
.(return 0 2>/dev/null)
executareturn
em uma subshell e suprime a mensagem de erro; posteriormente, o código de saída indica se o script foi originado (0
) ou não (1
), que é usado com os operadores&&
e||
para definir asourced
variável de acordo.return
no escopo de nível superior de um script de origem sairia do script.0
como oreturn
operando; ele observa: por ajuda do bash dereturn [N]
: "Se N for omitido, o status de retorno é o do último comando". Como resultado, a versão anterior [que usou apenasreturn
, sem um operando] produz resultado incorreto se o último comando no shell do usuário tiver um valor de retorno diferente de zero.ksh
Variável especial
${.sh.file}
é algo análogo a$BASH_SOURCE
; observe que${.sh.file}
causa um erro de sintaxe no bash, zsh e dash, portanto, execute-o condicionalmente em scripts de vários shell.Ao contrário do bash,
$0
e${.sh.file}
não são garantidos para ser exatamente idêntica no caso não-originária, como$0
pode ser um parente caminho, enquanto${.sh.file}
é sempre um completo caminho, por isso$0
deve ser resolvido para um caminho completo antes de comparar.zsh
$ZSH_EVAL_CONTEXT
contém informações sobre o contexto da avaliação - chame isso fora de uma função. Dentro de um script de origem [escopo de nível superior],$ZSH_EVAL_CONTEXT
termina com:file
.Advertência: Dentro de uma substituição de comando, o zsh acrescenta
:cmdsubst
, então teste$ZSH_EVAL_CONTEXT
por:file:cmdsubst$
lá.Usando apenas recursos POSIX
Se você está disposto a fazer certas suposições, você pode fazer uma razoável, mas não tolo à prova de palpite sobre se o script está sendo originada, com base em saber os nomes de arquivos binários das conchas que podem estar cumprindo seu script .
Notavelmente, isso significa que essa abordagem falhará se o seu script estiver sendo originado por outro script .
A seção "Como lidar com chamadas de origem" nesta resposta minha discute os casos extremos que não podem ser tratados com os recursos do POSIX apenas em detalhes.
Isso depende do comportamento padrão de
$0
, quezsh
, por exemplo, não exibe.Portanto, a abordagem mais segura é combinar os métodos robustos e específicos de shell acima com uma solução de fallback para todas as conchas restantes.
Ponta do chapéu para Stéphane Desneux e sua resposta para a inspiração (transformando minha expressão de declaração de shell cruzado em uma declaração
sh
compatívelif
e adicionando um manipulador para outras conchas).[1] user1902689 descobriu que
[[ $0 != "$BASH_SOURCE" ]]
produz um falso positivo quando você executa um script localizado no$PATH
, passando seu mero nome de arquivo para obash
binário; por exemplo,bash my-script
porque$0
é justomy-script
, enquanto$BASH_SOURCE
o caminho completo . Enquanto você normalmente não usaria essa técnica para invocar scripts no$PATH
- você os invocaria diretamente (my-script
) - é útil quando combinado com-x
a depuração .fonte
Depois de ler a resposta de @ DennisWilliamson, há alguns problemas, veja abaixo:
Como esta pergunta representa ksh e festança, há outra parte nesta resposta referente a ksh... ver abaixo.
Simples festança maneira
Vamos tentar (em tempo real porque essa festança poderia ;-):
Em
source
vez disso, uso off.
para facilitar a leitura (como.
é um alias parasource
):Observe que o número do processo não muda enquanto o processo permanece na origem :
Por que não usar
$_ == $0
comparaçãoPara garantir muitos casos, começo a escrever um script verdadeiro :
Copie isso para um arquivo chamado
testscript
:Agora poderíamos testar:
Isso está ok.
Isso está ok.
Mas, para testar um script antes de adicionar
-x
sinalizador:Ou para usar variáveis predefinidas:
Isso não vai mais funcionar.
Mover o comentário da quinta linha para a sexta daria uma resposta mais legível:
Mais difíceis: ksh agora...
Como eu não uso ksh muito, depois de ler na página de manual, existem minhas tentativas:
Copie isso em um
testfile.ksh
:Do que executá-lo duas vezes:
e veja:
Há alguma variável herdada em uma execução de origem , mas nada realmente relacionado ...
Você pode até verificar se
$SECONDS
está próximo0.000
, mas isso garante apenas casos de origem manual ...Você pode tentar verificar o que é pai ou mãe:
Coloque isso no seu
testfile.ksh
:Do que:
ou
ps ho cmd $PPID
, mas este trabalho apenas para um nível de subsessões ...Desculpe, não consegui encontrar uma maneira confiável de fazer isso, sob ksh.
fonte
[ "$0" = "$BASH_SOURCE" ] || [ -z "$BASH_SOURCE" ]
para scripts lidos via pipe (cat script | bash
)..
não é um alias parasource
, na verdade, é o contrário.source somescript.sh
é um bash-ismo e não é portátil,. somescript.sh
é POSIX e IIRC portátil.A
BASH_SOURCE[]
resposta (bash-3.0 e posterior) parece mais simples, embora nãoBASH_SOURCE[]
esteja documentada para funcionar fora de um corpo de função (atualmente funciona, em desacordo com a página do manual).A maneira mais robusta, como sugerido por Wirawan Purwanto, é verificar
FUNCNAME[1]
dentro de uma função :Então:
Isso equivale a verificar a saída de
caller
, os valoresmain
esource
distinguir o contexto do chamador. UsarFUNCNAME[]
salva a captura e a análise decaller
saída. Você precisa conhecer ou calcular a profundidade da chamada local para estar correta. Casos como um script originário de outra função ou script farão com que a matriz (pilha) seja mais profunda. (FUNCNAME
é uma variável de matriz bash especial, ela deve ter índices contíguos correspondentes à pilha de chamadas, desde que nunca sejaunset
.)(No bash-4.2 e posterior, você pode usar a forma mais simples
${FUNCNAME[-1]}
para o último item da matriz. Melhorado e simplificado graças ao comentário de Dennis Williamson abaixo.)No entanto, seu problema, conforme declarado, é " Eu tenho um script em que não quero que ele chame 'exit' se estiver sendo originado ". O
bash
idioma comum para esta situação é:Se o script estiver sendo originado,
return
ele terminará e retornará ao chamador.Se o script estiver sendo executado,
return
retornará um erro (redirecionado) eexit
encerrará o script normalmente. Ambosreturn
eexit
podem usar um código de saída, se necessário.Infelizmente, isso não funciona
ksh
(pelo menos não na versão derivada da AT&T que eu tenho aqui), tratareturn
como equivalente aexit
se invocado fora de uma função ou script de origem de pontos.Atualizado : o que você pode fazer nas versões contemporâneas
ksh
é verificar a variável especial.sh.level
definida para a profundidade da chamada da função. Para um script invocado, isso será inicialmente desconfigurado; para um script de origem de pontos, será definido como 1.Isso não é tão robusto quanto a versão do bash, você deve chamar
issourced()
no arquivo do qual está testando no nível superior ou em uma profundidade de função conhecida.(Você também pode estar interessado neste código no github, que usa uma
ksh
função de disciplina e alguns truques de trap de depuração para emular aFUNCNAME
matriz bash .)A resposta canônica aqui: http://mywiki.wooledge.org/BashFAQ/109 também oferece
$-
como outro indicador (embora imperfeito) do estado do shell.Notas:
FUNCNAME[]
mas enquanto apenas o último item dessa matriz for testado, não haverá ambiguidade.pdksh
. A coisa mais próxima que posso encontrar se aplica apenas apdksh
, onde cada fonte de um script abre um novo descritor de arquivo (começando com 10 para o script original). Quase certamente não é algo em que você deseja confiar ...fonte
${FUNCNAME[(( ${#FUNCNAME[@]} - 1 ))]}
obter o último item (inferior) da pilha? Então testar contra "main" (negar para OP) foi o mais confiável para mim.PROMPT_COMMAND
conjunto, seráFUNCNAME
exibido como o último índice da matriz, se eu executarsource sourcetest.sh
. Invertendo o cheque (à procura demain
como o último índice) parece mais robusto:is_main() { [[ ${FUNCNAME[@]: -1} == "main" ]]; }
.FUNCNAME
está disponível apenas em funções. De acordo com meus testes comdeclare -p FUNCNAME
,bash
comporta-se de maneira diferente. a v4.3 apresenta um erro fora das funções, enquanto a v4.4 fornecedeclare -a FUNCNAME
. Ambos (!) De retornomain
para${FUNCNAME[0]}
no script principal (se for executado), enquanto$FUNCNAME
não dá nada. E: Existem tantos scripts por aí "ab" usando$BASH_SOURCE
funções externas, que duvido que isso possa ou será alterado.Nota do editor: A solução desta resposta funciona de maneira robusta, mas é
bash
apenas. Pode ser simplificado para(return 2>/dev/null)
.TL; DR
Tente executar uma
return
declaração. Se o script não for originado, isso gerará um erro. Você pode pegar esse erro e prosseguir conforme necessário.Coloque isso em um arquivo e chame-o, digamos, test.sh:
Execute-o diretamente:
Fonte:
Para mim, isso funciona no zsh e no bash.
Explicação
A
return
instrução gerará um erro se você tentar executá-lo fora de uma função ou se o script não for originado. Tente isso em um prompt de shell:Você não precisa ver essa mensagem de erro, para redirecionar a saída para dev / null:
Agora verifique o código de saída. 0 significa OK (nenhum erro ocorreu), 1 significa que ocorreu um erro:
Você também deseja executar a
return
instrução dentro de um sub-shell. Quando areturn
instrução a executa. . . bem . . . retorna. Se você executá-lo em um sub-shell, ele retornará a partir desse sub-shell, em vez de retornar ao seu script. Para executar no sub-shell, envolva-o em$(...)
:Agora, você pode ver o código de saída do sub-shell, que deve ser 1, porque ocorreu um erro dentro do sub-shell:
fonte
$ readlink $(which sh)
dash
$ . test.sh
This script is sourced.
$ ./test.sh
This script is sourced.
return
deve ser feito no nível superior ( pubs.opengroup.org/onlinepubs/9699919799/utilities/… ). Odash
shell trata umreturn
no nível superior comoexit
. Outras conchas gostambash
ouzsh
não permitemreturn
no nível superior, que é o recurso que uma técnica como essa explora.$
antes do subshell. Ou seja, use em(return >/dev/null 2>&1)
vez de$(return >/dev/null 2>&1)
- mas depois ele pára de funcionar no bash.dash
, onde esta solução não funciona, atua comosh
no Ubuntu, por exemplo, essa solução geralmente não funcionash
. A solução funciona para mim no Bash 3.2.57 e 4.4.5 - com ou sem o$
antes(...)
(embora nunca haja uma boa razão para isso$
).return
Um valor de retorno explícito é interrompido ao executarsource
os scripts logo após um comando com saída incorreta. Propôs a edição de aprimoramento.FWIW, depois de ler todas as outras respostas, criei a seguinte solução para mim:
Isso funciona para todos os scripts, que começam com,
#!/bin/bash
mas também podem ser fornecidos por diferentes shells, para aprender algumas informações (como configurações) que são mantidas fora damain
função.Em vez das duas últimas linhas, você pode usar o código a seguir (na minha opinião menos legível) para não definir
BASH_SOURCE
outras conchas e permitirset -e
trabalhar emmain
:Esta receita de script possui as seguintes propriedades:
Se executado por
bash
da maneira normal,main
é chamado. Observe que isso não inclui uma chamada comobash -x script
(ondescript
não contém um caminho), veja abaixo.Se proveniente de
bash
,main
é chamado apenas, se o script de chamada tiver o mesmo nome. (Por exemplo, se ele se origina ou viabash -c 'someotherscript "$@"' main-script args..
ondemain-script
deve estar, o quetest
vê como$BASH_SOURCE
).Se originado / executado / lido /
eval
ed por um shell que não sejabash
,main
não é chamado (BASH_SOURCE
sempre é diferente de$0
).main
não é chamado sebash
lê o script de stdin, a menos que você defina$0
a string vazia da seguinte maneira:( exec -a '' /bin/bash ) <script
Se avaliado por
bash
comeval
(eval "`cat script`"
todas as aspas são importantes! ) De outro script, isso chamamain
. Seeval
for executado diretamente da linha de comando, será semelhante ao caso anterior, em que o script é lido a partir de stdin. (BASH_SOURCE
fica em branco, enquanto$0
normalmente/bin/bash
não é forçado a algo completamente diferente.)E se
main
não for chamado, ele retornarátrue
($?=0
).Isso não depende de comportamento inesperado (anteriormente escrevi sem documentos, mas não encontrei nenhuma documentação que você também não possa
unset
alterarBASH_SOURCE
):BASH_SOURCE
é uma matriz reservada do bash . Mas permitirBASH_SOURCE=".$0"
a mudança abriria uma lata de vermes muito perigosa, então minha expectativa é que isso não tenha efeito (exceto, talvez, algum aviso feio apareça em alguma versão futura dobash
).BASH_SOURCE
funcione fora das funções. No entanto, o oposto (que só funciona em funções) também não está documentado. A observação é que ele funciona (testado nasbash
v4.3 e v4.4, infelizmente nãobash
tenho mais a v3.x) e que muitos scripts quebrariam, se$BASH_SOURCE
parasse de funcionar como observado. Portanto, minha expectativa é que issoBASH_SOURCE
permaneça como está para as versões futurasbash
também.( return 0 )
, Considere , o que fornece0
se originado e1
se não for originado. Isso é um pouco inesperado, não apenas para mim , e (de acordo com as leituras), o POSIX diz que oreturn
subshell é um comportamento indefinido (e oreturn
aqui é claramente de um subshell). Talvez esse recurso acabe recebendo amplo uso suficiente para que não possa mais ser alterado, mas no AFAICS há uma chance muito maior de que algumabash
versão futura acidental mude o comportamento de retorno nesse caso.Infelizmente
bash -x script 1 2 3
não funcionamain
. (Comparescript 1 2 3
ondescript
não há caminho). A seguir pode ser usado como solução alternativa:bash -x "`which script`" 1 2 3
bash -xc '. script' "`which script`" 1 2 3
bash script 1 2 3
não é executadomain
pode ser considerado um recurso.Observe que as
( exec -a none script )
chamadasmain
(bash
não passam$0
para o script, para isso você precisa usar-c
como mostrado no último ponto).Assim, exceto em alguns casos de canto,
main
só é chamado quando o script é executado da maneira usual. Normalmente é isso que você quer, especialmente porque não possui código complexo e difícil de entender.Por que acho que essa é uma boa maneira geral de resolver o desafio
Se você tiver algo que possa ser originado por várias conchas, ele deverá ser compatível. No entanto (leia as outras respostas), pois não há uma maneira (fácil de implementar) portátil de detectar o
source
ing, você deve alterar as regras .Ao impor que o script deve ser executado por
/bin/bash
, você faz exatamente isso.Isso resolve todos os casos, mas , nesse caso, o script não pode ser executado diretamente:
/bin/bash
não está instalado ou não funciona (por exemplo, em um ambiente de inicialização)curl https://example.com/script | $SHELL
bash
é recente o suficiente. É relatado que esta receita falha em determinadas variantes. Portanto, verifique se ela funciona no seu caso.)No entanto, não consigo pensar em nenhuma razão real em que você precise disso e também na capacidade de obter o mesmo script em paralelo! Geralmente você pode envolvê-lo para executar o
main
manualmente. Curtiu isso:$SHELL -c '. script && main'
{ curl https://example.com/script && echo && echo main; } | $SHELL
$SHELL -c 'eval "`curl https://example.com/script`" && main'
echo 'eval "`curl https://example.com/script`" && main' | $SHELL
Notas
Esta resposta não teria sido possível sem a ajuda de todas as outras respostas! Mesmo os errados - o que inicialmente me fez postar isso.
Atualização: Editada devido às novas descobertas encontradas em https://stackoverflow.com/a/28776166/490291
fonte
/bin/sh
está efetivamentebash
no modo POSIX, atribuindo aBASH_SOURCE
quebra de seu script. Em outras conchas (dash
,ksh
,zsh
), invocando o seu script passando-a como um argumento de arquivo diretamente para o executável shell avarias (por exemplo,zsh <your-script>
vai fazer o seu roteiro engano pensar que é originária ). (Você já mencionar que canalizando o mau funcionamento do código, em todas as conchas.). <your-script>
(sourcing) funcione com todos os shells do tipo POSIX, em princípio, só faz sentido se o script foi escrito explicitamente para usar somente os recursos do POSIX, de modo a impedir que recursos específicos de um shell interrompam a execução em outras conchas; usar uma linha shebang do Bash (em vez de#!/bin/sh
) é, portanto, confuso - pelo menos sem um comentário conspícuo. Por outro lado, se seu script for executado apenas a partir do Bash (mesmo que não considerando quais recursos talvez não sejam portáteis), é melhor recusar a execução em shells que não sejam do Bash.main
, mas faz isso neste caso! E quando originados por/bin/sh
, ou sejabash --posix
, o mesmo acontece neste caso, e isso também está errado.Isso funciona mais tarde no script e não depende da variável _:
ou
fonte
Vou dar uma resposta específica ao BASH. Korn shell, desculpe. Suponha que seu nome de script seja
include2.sh
; então faça uma função dentro doinclude2.sh
chamadoam_I_sourced
. Aqui está minha versão demo deinclude2.sh
:Agora tente executá-lo de várias maneiras:
Portanto, isso funciona sem exceção, e não está usando o
$_
material quebradiço . Este truque usa o recurso de introspecção do BASH, ou seja, variáveis embutidasFUNCNAME
eBASH_SOURCE
; consulte a documentação deles na página de manual do bash.Apenas duas ressalvas:
1) a chamada para
am_I_called
deve ocorrer no script de origem, mas não dentro de nenhuma função, para que não${FUNCNAME[1]}
retorne outra coisa. Sim ... você poderia ter verificado${FUNCNAME[2]}
- mas você apenas torna sua vida mais difícil.2) A função
am_I_called
deve residir no script de origem se você quiser descobrir qual o nome do arquivo que está sendo incluído.fonte
Gostaria de sugerir uma pequena correção à resposta muito útil de Dennis , para torná-la um pouco mais portátil, espero:
porque
[[
não é reconhecido pelo shell compatível Debian POSIX (um pouco retentivo anal)dash
. Além disso, pode-se precisar das aspas para proteger contra nomes de arquivos contendo espaços, novamente no referido shell.fonte
$_
é bastante quebradiço. Você deve verificá-lo como a primeira coisa que faz no script. E mesmo assim, não é garantido que contenha o nome do seu shell (se originado) ou o nome do script (se executado).Por exemplo, se o usuário definiu
BASH_ENV
, na parte superior de um script,$_
contém o nome do último comando executado no diretórioBASH_ENV
script.A melhor maneira que eu encontrei é usar
$0
assim:Infelizmente, esse caminho não funciona imediatamente no zsh devido à
functionargzero
opção de fazer mais do que o nome sugere e estar ativado por padrão.Para contornar isso, eu coloquei
unsetopt functionargzero
no meu.zshenv
.fonte
Eu segui mklement0 expressão compacta .
Isso é legal, mas notei que ele pode falhar no caso do ksh quando invocado da seguinte maneira:
(ele acha que é originário e não porque executa um subshell). Mas a expressão funcionará para detectar isso:
Além disso, mesmo que a expressão seja compacta, a sintaxe não é compatível com todos os shells.
Então terminei com o seguinte código, que funciona para bash, zsh, dash e ksh
Sinta-se livre para adicionar conchas exóticas suporte :)
fonte
ksh 93+u
,ksh ./myscript.sh
funciona bem para mim (com a minha declaração) - qual versão você está usando?/proc/$$/cmdline
) e se concentradash
apenas (que também atua como osh
Ubuntu, por exemplo). Se você estiver disposto a fazer certas suposições, poderá examinar$0
um teste razoável - mas incompleto - que seja portátil.sh
/dash
também, em um adendo à minha resposta.Eu não acho que exista uma maneira portátil de fazer isso no ksh e no bash. No bash, você pode detectá-lo usando a
caller
saída, mas não acho que exista equivalente no ksh.fonte
$0
trabalha embash
,ksh93
, epdksh
. Eu não tenhoksh88
que testar.Eu precisava de um one-liner que funcione em [mac, linux] com bash.version> = 3 e nenhuma dessas respostas se encaixa na conta.
fonte
bash
solução funciona bem (você pode simplificar$BASH_SOURCE
), mas aksh
solução não é robusta: se o seu script estiver sendo originado por outro script , você receberá um falso positivo.Direto ao ponto: você deve avaliar se a variável "$ 0" é igual ao nome do seu Shell.
Como isso:
Via SHELL :
Via SOURCE :
É muito difícil ter uma maneira 100% portátil de detectar se um script foi originado ou não.
Em relação à minha experiência (7 anos com Shellscripting) , a única maneira segura (sem depender de variáveis de ambiente com PIDs e assim por diante), que não é segura devido ao fato de ser algo VARIÁVEL ), você deve:
Ambas as opções não podem ser dimensionadas automaticamente, mas é a maneira mais segura.
Por exemplo:
quando você origina um script por meio de uma sessão SSH, o valor retornado pela variável "$ 0" (ao usar origem ) é -bash .
OU
fonte
/bin/bash -c '. ./check_source.sh'
dáThe script WAS NOT sourced.
. Mesmo bug:ln -s /bin/bash pumuckl; ./pumuckl -c '. ./check_source.sh'
->The script WAS NOT sourced.
Acabei checando
[[ $_ == "$(type -p "$0")" ]]
Quando usado
curl ... | bash -s -- ARGS
para executar scripts remotos on-the-fly, o $ 0 será apenas embash
vez do normal/bin/bash
quando executar o arquivo de script real, então eu usotype -p "$0"
para mostrar o caminho completo do bash.teste:
fonte
Esta é uma derivação de algumas outras respostas, em relação ao suporte de shell cruzado "universal". É reconhecidamente muito semelhante a https://stackoverflow.com/a/2942183/3220983 em particular, embora um pouco diferente. O ponto fraco disso é que um script de cliente deve respeitar como usá-lo (ou seja, exportando uma variável primeiro). A força é que isso é simples e deve funcionar "em qualquer lugar". Aqui está um modelo para o seu prazer de cortar e colar:
Nota:
export
Apenas certifique-se de que esse mecanismo possa ser estendido em subprocessos.fonte