Como alterar um argumento de linha de comando no Bash?

92

Existe uma maneira de alterar os argumentos da linha de comando em um script Bash. Digamos, por exemplo, um script Bash é chamado da seguinte maneira:

./foo arg1 arg2  

Existe uma maneira de alterar o valor de arg1 no script? Diga, algo como

$1="chintz"
Sriram
fonte

Respostas:

147

Você tem que redefinir todos os argumentos. Para mudar, por exemplo $3:

$ set -- "${@:1:2}" "new" "${@:4}"

Basicamente, você configura todos os argumentos com seus valores atuais, exceto aquele (s) que deseja alterar. set --também é especificado por POSIX 7 .

A "${@:1:2}"notação é expandida para os dois (daí os 2na notação) argumentos posicionais começando do deslocamento 1(isto é $1). É uma abreviação de "$1" "$2"neste caso, mas é muito mais útil quando você deseja substituir, por exemplo "${17}".

thkala
fonte
1
então, para alterar $ 3, devo alterar $ 1 e $ 2 também, certo? E transformá-los em quê? O que significa "redefinir"?
Sriram
Obrigado pelo truque! Tive dificuldade em usar isso para nomes de arquivos com espaços incorporados. Para qualquer outra pessoa que possa ter esse problema, tente colocar evalna frente da fila de acordo com isso .
cxw
2
Isso é normal quando você sabe a posição do parâmetro que deseja alterar. E se você realmente não souber e precisar alterá-lo dinamicamente? Tentei com $ set - "$ {: 1: $ pivot}", mas não aceita uma variável lá.
Daniele Segato
1
Como posso fazer a mesma coisa de dentro de uma função? Sua solução parece não funcionar quando chamada de dentro de uma função.
Hashken
2
Você não pode alterar os parâmetros posicionais de um script de dentro de uma função - os próprios argumentos da função os ocultam. Você pode, no entanto, armazená-los em uma matriz e operar nela.
thkala
22

Otimizando para legibilidade e manutenção, você pode ser melhor atribuir $1e $2para variáveis ​​mais significativas (eu não sei, input_filename = $1e output_filename = $2ou algo assim) e, em seguida, sobrescrever uma dessas variáveis ​​( input_filename = 'chintz'), deixando a entrada para o script inalterada, caso seja necessário em outro lugar.

Johnsyweb
fonte
Eu queria uma abordagem em que pudesse alterar um dos argumentos de entrada em si. Eu precisava fazer isso porque queria retornar um valor do script. A resposta sugerida por thkala funcionou bem. Obrigado pela resposta!!!
Sriram
3
@Johnsyweb Concordo. Para facilitar a leitura, o seu é o melhor método.
DSS de
1
"Você está melhor" sempre depende do caso de uso, que não é fornecido.
Scott
2
@Scott 7 anos mais velho e mais experiência do que eu tinha quando escrevi esta resposta, estou inclinado a concordar com você.
Johnsyweb,
Exemplo onde isso não funcionaria (além de usar algo como $ FIRST_PARAMETER): tendo o uso e o significado do parâmetro dependendo do valor real.
Igor Stoppa