Como comentário goldilocks e referências da humanidade descrever,
shift
atribui novamente os parâmetros de posição ( $1
, $2
, etc.) de modo a que $1
assume o valor antigo $2
,
$2
assume o valor $3
, etc. *
O valor antigo $1
é descartado. ( $0
não é alterado.) Alguns motivos para fazer isso incluem:
- Permite acessar o décimo argumento (se houver) com mais facilidade.
$10
não funciona - é interpretado como $1
concatenado com um 0
(e, portanto, pode produzir algo como Hello0
). Depois de a shift
, o décimo argumento se torna $9
. (No entanto, na maioria das conchas modernas, você pode usar ${10}
.)
- Como o Bash Guide for Beginners demonstra, ele pode ser usado para percorrer os argumentos. IMNSHO, isso é desajeitado;
for
é muito melhor para isso.
- Como no exemplo de script, facilita o processamento de todos os argumentos da mesma maneira, exceto por alguns. Por exemplo, no seu script,
$1
e $2
são cadeias de texto, enquanto $3
e todos os outros parâmetros são nomes de arquivos.
Então, aqui está como isso acontece. Suponha que seu script seja chamado Patryk_script
e seja chamado como
Patryk_script USSR Russia Treaty1 Atlas2 Pravda3
O script vê
$1 = USSR
$2 = Russia
$3 = Treaty1
$4 = Atlas2
$5 = Pravda3
A instrução ostr="$1"
define a variável ostr
como USSR
. A primeira shift
instrução altera os parâmetros posicionais da seguinte maneira:
$1 = Russia
$2 = Treaty1
$3 = Atlas2
$4 = Pravda3
A instrução nstr="$1"
define a variável nstr
como Russia
. A segunda shift
instrução altera os parâmetros posicionais da seguinte maneira:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
E então as for
mudanças de loop USSR
( $ostr
) para Russia
( $nstr
) nos arquivos Treaty1
, Atlas2
e Pravda3
.
Existem alguns problemas com o script.
para arquivo em $ @; Faz
Se o script for chamado como
Patryk_script Tratado da URSS Rússia1 "Atlas Mundial2" Pravda3
vê
$ 1 = URSS
$ 2 = Rússia
$ 3 = Tratado1
US $ 4 = Atlas Mundial2
$ 5 = Pravda3
mas, porque $@
não é citado, o espaço World Atlas2
não é citado, eo for
ciclo pensa que tem quatro arquivos: Treaty1
, World
, Atlas2
, e Pravda3
. Isso deve ser
para arquivo em "$ @"; Faz
(para citar qualquer caractere especial nos argumentos) ou simplesmente
para o arquivo
(que é equivalente à versão mais longa).
eval "sed 's /" $ ostr "/" $ nstr "/ g' $ arquivo"
Não é necessário que isso seja uma eval
passagem de entrada desmarcada do usuário para uma eval
pode ser perigosa. Por exemplo, se o script for chamado como
Patryk_script "'; rm *;'" Tratado da Rússia1 Atlas2 Pravda3
vai executar rm *
! Essa é uma grande preocupação se o script puder ser executado com privilégios mais altos que os do usuário que o invoca; por exemplo, se pode ser executado via sudo
ou invocado a partir de uma interface da web. Provavelmente não é tão importante se você apenas usá-lo como você mesmo, em seu diretório. Mas pode ser alterado para
sed "s / $ ostr / $ nstr / g" "$ arquivo"
Isso ainda tem alguns riscos, mas são muito menos graves.
if [ -f $file ]
, > $file.tmp
e mv $file.tmp $file
devem ser if [ -f "$file" ]
, > "$file.tmp"
e mv "$file.tmp" "$file"
, respectivamente, manipular nomes de arquivos que possam ter espaços (ou outros caracteres engraçados) neles. (O eval "sed …
comando também gerencia nomes de arquivos que possuem espaços.)
* shift
aceita um argumento opcional: um número inteiro positivo que especifica quantos parâmetros devem ser alterados. O padrão é um ( 1
). Por exemplo, shift 4
causas $5
para se tornar $1
,
$6
se tornar $2
e assim por diante. (Observe que o exemplo no Guia Bash para iniciantes está errado.) E, portanto, seu script pode ser modificado para dizer
ostr="$1"
nstr="$2"
shift 2
o que pode ser considerado mais claro.
Nota final / Aviso:
A linguagem do prompt de comando do Windows (arquivo em lote) também suporta um SHIFT
comando, que basicamente faz a mesma coisa que o shift
comando nos shells do Unix, com uma diferença marcante, que vou esconder para tentar impedir que as pessoas se confundam com ele:
- Um comando como
SHIFT 4
é um erro, gerando uma mensagem de erro "Parâmetro inválido no comando SHIFT".
SHIFT /n
, onde n
é um número inteiro entre 0 e 8, é válido - mas não muda os horários . Ela muda uma vez, começando com o n º argumento. Assim, faz com que o quinto argumento se torne e assim por diante, deixando os argumentos de 0 a 3 sozinhos.n
SHIFT /4
%5
%4,
%6
%5
pushd
epopd
).