fbpx

Comandos Linux – Comando shift

Comando shift do Linux

comando shift

Em sistemas operacionais do tipo Unix, shift é um comando interno do shell Bash . Quando executado , ele muda os parâmetros posicionais (como argumentos passados ​​para um script bash ) para a esquerda, colocando cada parâmetro em uma posição inferior.

Descrição

Quando você executa o turno , os parâmetros posicionais atuais são deslocados para a esquerda n vezes. O parâmetro posicional x recebe o valor do parâmetro x + n . Se o parâmetro x + n não existir, o parâmetro x está desativado .

Se não especificado, o valor padrão de n é 1 . Portanto, os comandos ” shift 1 ” e ” shift ” (sem argumento) fazem a mesma coisa.

Se um parâmetro é deslocado para uma posição com um número menor que 1, ele “cai” – seu valor é descartado. Portanto, a mudança de comando sempre descartará o valor anterior de $ 1 e a mudança 2 sempre descartará os valores anteriores de $ 1 e $ 2 .

O parâmetro posicional especial $ 0 é excluído de todas as operações shift e nunca modificado pelo comando shift .

Sintaxe

turno [ n ]

O comando shift usa apenas um argumento:

nO número de posições em que os parâmetros devem ser deslocados para a esquerda. Este valor pode ser qualquer número inteiro não negativo . Se n for zero ( 0 ), nenhum deslocamento de parâmetro será realizado. O valor padrão de n é 1 .

Status de saída

Quando o shift sai, ele retorna um status de saída 0 (sem erro), a menos que: n seja negativo ou n seja maior que o número atual de parâmetros posicionais, caso em que o status de saída é diferente de zero.

Parâmetros posicionais no bash

No bash, sempre que um comando é executado, o ambiente para esse comando inclui variáveis ​​especiais que contêm os parâmetros individuais fornecidos ao comando.

O nome de cada uma dessas variáveis ​​é um número, correspondente à posição desse parâmetro na linha de comando.

Por exemplo, considere o seguinte comando:

mv file_old.txt file_new.txt

Este comando possui três parâmetros posicionais, numerados da seguinte maneira:

ParâmetroPosiçãoDescrição
mv0 0O comando mv , que move arquivos. Nesse caso, ele renomeará file_old.txt para file_new.txt “movendo-o” para o novo nome do arquivo .
file_old.txt1O nome do arquivo original.
file_new.txt2O novo nome do arquivo.

O primeiro parâmetro, 0 , contém o nome do comando. Se não houver argumentos, este será o único parâmetro posicional.

Quando argumentos são incluídos após um comando, cada um é armazenado nas variáveis ​​do shell denominadas 1 , 2 etc. Como qualquer outra variável do shell, seu valor pode ser referenciado colocando um cifrão antes do nome da variável. Portanto, o valor do parâmetro posicional 1 pode ser referenciado com $ 1 , o valor do parâmetro 2 pode ser referenciado com $ 2 , etc.

Parâmetros com um número 10 ou superior podem ser referenciados colocando o número entre colchetes, por exemplo $ {10} , $ {11} ou $ {12345} .

O Bash rastreia o número total de parâmetros posicionais. Esse número é armazenado na variável especial do shell $ # .

O valor de $ # diminui n sempre que você executa o turno .

Parâmetro posicional especial zero

O parâmetro posicional zero ( 0 ) contém o nome do comando que foi usado para iniciar o processo atual , conforme foi executado. Você sempre pode descobrir qual comando foi usado para iniciar o processo atual, verificando o valor dessa variável.

Por exemplo: em um prompt do bash, você pode executar echo $ 0 para ver o comando que iniciou sua sessão atual do bash:

eco $ 0
/ bin / bash

Este é o local do executável do bash .

Porém, existem diferentes maneiras de executar um arquivo executável – por exemplo, muitos programas são executados usando um link simbólico (link simbólico). Se você executar um comando usando um link simbólico, $ 0 conterá o nome do link que você usou.

Por exemplo, você pode criar um link simbólico para bash em seu diretório pessoal :

ln -s / bin / bash ~ / mybash

E torne o link simbólico executável, usando chmod :

chmod u + x ~ / mybash

Em seguida, você pode iniciar um novo processo filho do bash executando o link simbólico:

~ / mybash

Agora você está em um novo shell bash, dentro do shell anterior. Se você executar echo $ 0 , verá a diferença:

eco $ 0
/ home / esperança / mybash

Este é o caminho completo para o diretório inicial, conforme expandido pelo bash quando você usou o alias ~ (um til ). Você pode digitar exit agora, para retornar ao seu shell bash original.

Exemplos

Mudança de parâmetros

Vamos criar um script que aceite argumentos. Veremos como os argumentos são armazenados no ambiente como parâmetros posicionais e como a mudança os afeta.

Crie um novo script com seu editor de texto favorito, como pico ou vim . O script deve ficar assim:

#! / bin / bash
turno 0
eco 0: $ 0
eco 1: $ 1
eco 2: $ 2
eco 3: $ 3
eco 4: $ 4

A primeira linha, que começa com #! (a ” shebang “) define qual programa shell deve ser usado para executar o script.

A segunda linha (” turno 0 “) não faz nada – ainda. Depois de executar o script assim, mudaremos 0 para outro número.

Agora, salve isso em um arquivo chamado myargs.sh e saia do editor de texto.

Torne o myargs.sh executável:

chmod u + x ./myargs.sh

Em seguida, execute-o e dê alguns argumentos:

./myargs.sh um dois três quatro cinco
0: ./myargs.sh
1 um
2: dois
3: três
4: quatro

Nesta saída, podemos ver os valores dos parâmetros posicionais 0 – 4 . (O valor de $ 5 é ” cinco “, mas não estamos usando esse valor em nosso script.)

Esses valores são específicos ao nosso comando atual – o script. Quando o script é concluído, esses valores retornam aos seus valores antes da execução do script. Então agora, no prompt de comando, você pode executar:

eco $ 0, $ 1, $ 2, $ 3, $ 4.
/ bin / bash,,,,.

Estes são os valores para a nossa sessão do bash. $ 0 é o local do executável do bash e os outros parâmetros não têm valor.

Agora vamos mudar o turno 0 para o turno 1 . Abra o script no seu editor de texto e altere a segunda linha para que o script fique assim:

$! / bin / bash
turno # igual ao turno 1
eco 1: $ 1
eco 2: $ 2
eco 3: $ 3
eco 4: $ 4

Tudo depois da marca de hash (” # “) na linha 2 é um comentário e será ignorado quando o script for executado.

Salve o arquivo e saia do editor de texto. Em seguida, execute o script novamente:

./myargs.sh um dois três quatro cinco
0: ./myargs.sh
1: dois
2: três
3: quatro
4: cinco

Observe que a posição de todos os parâmetros é reduzida em um. O valor original de $ 1 foi descartado e o valor de $ 5 agora está em $ 4 . O valor de $ 0 não foi alterado.

Mas executar o turno apenas uma vez não é muito útil. Normalmente, você desejará executá-lo várias vezes, em um loop. Podemos reescrever o script acima como um loop, onde cada iteração altera os parâmetros uma vez. No seu editor de texto, altere o script para ficar assim:

#! / bin / bash
for ((i = 0; i <= 4; i ++));
Faz
  eco Deslocado $ i tempo (s):
  eco -----------------
  eco 1: $ 1
  eco 2: $ 2
  eco 3: $ 3
  eco 4: $ 4
  eco
  mudança
feito

Observe que shift é o último comando do loop. Isso nos permite fazer algo com os parâmetros antes que eles sejam alterados. Então, como passo final, alteramos os parâmetros e executamos o loop novamente.

Salve suas alterações, saia do editor de texto e execute o script. Ele fará um loop cinco vezes (com i incrementando de 0 a 4 , uma vez por loop). Cada ciclo irá mudar os valores de uma vez, e eco os valores 0 – 4 para o terminal.

./myargs.sh um dois três quatro cinco
0 vezes alteradas:
------------------
1 um
2: dois
3: três
4: quatro
Mudou 1 vez (es):
------------------
1: dois
2: três
3: quatro
4: cinco
Mudou 2 vezes:
------------------
1: três
2: quatro
3: cinco
4:
Mudou 3 vezes:
------------------
1: quatro
2: cinco
3:
4:
Mudou 4 vezes:
------------------
1: cinco
2:
3:
4:

Agora que vimos como os parâmetros são alterados, vamos criar um script que tenha um objetivo prático.

Exemplo do mundo real

O script a seguir, clean-old-files.sh , aceita uma lista de nomes de diretórios como parâmetros na linha de comandos. Ele verifica cada diretório nomeado em busca de arquivos que não foram acessados ​​há mais de um ano e os exclui.

#! / bin / bash
# Examine os diretórios em busca de arquivos antigos (mais de 365 dias) e exclua-os.
USAGE = "Uso: $ 0 dir1 dir2 dir3 ..."
if ["$ #" == "0"]; então # Se zero argumento for fornecido,
  echo "Erro: nenhum nome de diretório fornecido."
  eco "$ USAGE" # exibe uma mensagem de ajuda
  saia 1 # e retorne um erro.
fi
while (("$ #")); Embora ainda haja argumentos a serem alterados ...
  while IFS = ler -r -d $ '\ 0' arquivo; Faz
    echo "Removendo o arquivo $ ..."
    arquivo rm $
  done <<(encontre o tipo "$ 1" f -atime +365 -print0)
  mudança
feito
eco "Concluído".
saída 0

Vamos dar uma olhada nas partes individuais desse script e analisar o que elas fazem:

USAGE = "Uso: $ 0 dir1 dir2 dir3 ..."
if ["$ #" == "0"]; então
  echo "Erro: nenhum nome de diretório fornecido."
  eco "$ USAGE"
  saída 1
fi

Nesta instrução if condicional , o script verifica se há algum argumento. O teste usa a notação entre colchetes ( [ … ] ), que é equivalente ao uso do teste de comando interno . A variável especial do shell $ # contém o número total de parâmetros posicionais. Se o seu valor for igual a zero, significa que o usuário não forneceu nenhum nome de diretório, então ecoamos uma mensagem de ajuda e encerramos o script com um erro (status de saída 1 ).

while (("$ #")); Faz

Caso contrário, prosseguimos para o loop while externo , que usa avaliação de parênteses duplos para ver se $ # é verdadeiro – ou seja, se seu valor for diferente de zero. Toda vez que o loop inicia, se $ # for zero, a expressão é avaliada como falsa e o loop sai.

GorjetaAs expressões ((“$ #”)) e [“$ #”! = “0”] fornecem resultados equivalentes e são funcionalmente intercambiáveis.

Em seguida, vamos olhar para os dois lados do loop while interno:

  while IFS = ler -r -d $ '\ 0' arquivo; Faz

Esta linha diz: enquanto houver itens a serem lidos , onde itens individuais são delimitados ( -d ) por um caractere nulo ( $ ‘\ 0’ ), leia um item no arquivo variável e execute os comandos dentro do loop.

Os itens são fornecidos pela linha no final do loop:

  done <<(encontre o tipo "$ 1" f -atime +365 -print0)

Esta linha diz: encontre todos os arquivos, iniciando a pesquisa no diretório dir1 (no parâmetro posicional $ 1 ), que foi acessado pela última vez ( -atime ) há mais de ( + ) 365 dias atrás. Delimite a lista de nomes de arquivos correspondentes com caracteres nulos ( -print0 ).

O comando find está entre <( … ) , que usa substituição de processo para tratar a saída como se fosse um arquivo. O conteúdo desse “arquivo” é redirecionado ( < ) para o loop while interno. Lá, read interpreta tudo até um caractere nulo como o próximo nome de arquivo e atribui esse nome ao arquivo variável . Então, o interior do loop é executado:

    echo "Removendo o arquivo $ ..."
    arquivo rm $

Que imprime o nome do arquivo e remove o arquivo.

O loop interno continua até que não haja mais nomes de arquivos, portanto, read retorna false. O loop interno sai para o loop externo, onde, nós …

  mudança

altere os parâmetros posicionais, para que o dir2 ( $ 2 ) seja agora dir1 ( $ 1 ). O antigo $ 1 é descartado e o $ # é automaticamente decrementado por 1.

feito

Volte ao início do loop while externo . Se não houver mais parâmetros posicionais, o teste ((“$ #”)) retorna false, o loop externo sai e …

eco "Concluído".
saída 0

Saímos com sucesso (status de saída 0 ).

A execução do script terá a seguinte aparência:

./clean-old-files.sh mydir1 mydir2
Removendo mydir1 / subdir1 / Netscape-Navigator-1.0.zip ...
Removendo o mydir1 / subdir2 / meu-logo-a-ser-terminado-novel.rtf ...
Removendo mydir2 / subdir1 / grunge-o-novo-fenômeno.doc ...
Removendo mydir2 / subdir2 / my-geocities-page.htm ...
Removendo mydir2 / subdir3 / half-life-2-leaked-beta.rar ...
Feito.

getopts – Analisa argumentos passados ​​para um shell script.

22 de novembro de 2019

Sobre nós

A Linux Force Brasil é uma empresa que ama a arte de ensinar. Nossa missão é criar talentos para a área de tecnologia e atender com excelência nossos clientes.

CNPJ: 13.299.207/0001-50
SAC:         0800 721 7901

[email protected]

Comercial  Comercial: (11) 3796-5900

Suporte:    (11) 3796-5900
[email protected]

Copyright © Linux Force Security  - Desde 2011.