Estou tentando escrever uma função em bash que acessará os argumentos de linha de comando do script, mas eles foram substituídos pelos argumentos posicionais da função. Existe alguma maneira de a função acessar os argumentos da linha de comando se eles não forem passados explicitamente?
# Demo function
function stuff {
echo $0 $*
}
# Echo's the name of the script, but no command line arguments
stuff
# Echo's everything I want, but trying to avoid
stuff $*
bash
command-line-arguments
argv
DonGar
fonte
fonte
$*
é extremamente problemático - ele mudará./yourScript "first argument" "second argument"
para./yourscript "first" "argument" "second" "argument"
, ou mudará./yourscript '*.txt'
para algo como,./yourscript one.txt two.txt
apesar das aspas.Respostas:
Minha leitura do manual de referência do bash diz que essas coisas são capturadas em BASH_ARGV, embora fale muito sobre "a pilha".
Salvar em f.sh
fonte
Se você quiser ter seus argumentos no estilo C (matriz de argumentos + número de argumentos), você pode usar
$@
e$#
.$#
fornece o número de argumentos.$@
dá a você todos os argumentos. Você pode transformar isso em uma matriz porargs=("$@")
.Então, por exemplo:
Observe que aqui
${args[0]}
está realmente o primeiro argumento e não o nome do seu script.fonte
args
array de dentro de uma função, se você inicializá-lo de antemão conforme descrito.echo "${args[0]} ${args[1]} ${args[2]}"
, ou os argumentos estão sujeitos à expansão do nome do arquivo.Edit: por favor, veja meu comentário sobre a questão
fonte
O comentário de Ravi é essencialmente a resposta. As funções usam seus próprios argumentos. Se quiser que eles sejam iguais aos argumentos da linha de comando, você deve passá-los. Caso contrário, você está claramente chamando uma função sem argumentos.
Dito isso, você poderia, se quiser, armazenar os argumentos da linha de comando em uma matriz global para usar em outras funções:
Você tem que acessar os argumentos de linha de comando através da
commandline_args
variável, não$@
,$1
,$2
, etc., mas eles estão disponíveis. Não tenho conhecimento de nenhuma maneira de atribuir diretamente ao array de argumentos, mas se alguém conhecer um, por favor, esclareça-me!Além disso, observe a maneira como usei e citei
$@
- é assim que você garante que os caracteres especiais (espaços em branco) não sejam bagunçados.fonte
fonte
Pode-se fazer assim também
Agora chame seu script de
fonte
function print() {
é um amálgama entre duas formas de declaração de função diferentes -function print {
, que é a sintaxe ksh legada que o bash suporta para compatibilidade com versões anteriores com ksh pré-POSIX (ou seja, pré-1991) eprint() {
, que é padronizado por POSIX. Considere usar um ou outro para compatibilidade mais ampla com outros shells; veja também wiki.bash-hackers.org/scripting/obsoleteVocê pode usar a palavra-chave shift (operador?) Para iterar por eles. Exemplo:
fonte
function print() {
é um amálgama entre duas formas de declaração de função diferentes -function print {
, que é a sintaxe legada do ksh que o bash suporta para compatibilidade com versões anteriores do ksh pré-POSIX (ou seja, pré-1991) eprint() {
, que é padronizado pelo POSIX. Considere usar um ou outro para compatibilidade mais ampla com outros shells; veja também wiki.bash-hackers.org/scripting/obsoleteMinha solução:
Crie um script de função que seja chamado antes de todas as outras funções sem passar nenhum argumento para ele, como este:
Depois disso, você pode chamar o init e usar o ORIGOPT var conforme necessário, como um plus, eu sempre atribuo uma nova var e copio o conteúdo do ORIGOPT em minhas novas funções, dessa forma você pode ter certeza de que ninguém vai tocar nele ou mude.
Eu adicionei espaços e travessões para tornar mais fácil analisá-lo com 'sed -E' também o bash não o passará como referência e fará ORIGOPT crescer conforme as funções são chamadas com mais argumentos.
fonte