Linux Professional Institute Learning Logo.
Ir para o conteúdo principal
  • Home
    • Todos os recursos
    • LPI Materiais Didáticos
    • Colabore Conosco
    • Publishing Partners
    • Seja um Publishing Partner
    • Quem Somos
    • FAQ
    • Colaboradores
    • Contato
  • LPI.org
105.2 Lição 2
Tópico 105: Shells e scripts do Shell
105.1 Personalizar e trabalhar no ambiente shell
  • 105.1 Lição 1
  • 105.1 Lição 2
  • 105.1 Lição 3
105.2 Editar e escrever scripts simples
  • 105.2 Lição 1
  • 105.2 Lição 2
Tópico 106: Interfaces de usuário e Desktops
106.1 Instalar e configurar o X11
  • 106.1 Lição 1
106.2 Desktops gráficos
  • 106.2 Lição 1
106.3 Acessibilidade
  • 106.3 Lição 1
Tópico 107: Tarefas administrativas
107.1 Administrar contas de usuário, grupos e arquivos de sistema relacionados
  • 107.1 Lição 1
  • 107.1 Lição 2
107.2 Automatizar e agendar tarefas administrativas de sistema
  • 107.2 Lição 1
  • 107.2 Lição 2
107.3 Localização e internacionalização
  • 107.3 Lição 1
Tópico 108: Serviços essenciais do sistema
108.1 Manutenção da data e hora do sistema
  • 108.1 Lição 1
  • 108.1 Lição 2
108.2 Log do sistema
  • 108.2 Lição 1
  • 108.2 Lição 2
108.3 Fundamentos de MTA (Mail Transfer Agent)
  • 108.3 Lição 1
108.4 Configurar impressoras e impressão
  • 108.4 Lição 1
Tópico 109: Fundamentos de Rede
109.1 Fundamentos de protocolos de internet
  • 109.1 Lição 1
  • 109.1 Lição 2
109.2 Configuração persistente de rede
  • 109.2 Lição 1
  • 109.2 Lição 2
109.3 Soluções para problemas simples de rede
  • 109.3 Lição 1
  • 109.3 Lição 2
109.4 Configurar DNS cliente
  • 109.4 Lição 1
Tópico 110: Segurança
110.1 Tarefas administrativas de segurança
  • 110.1 Lição 1
110.2 Configurar a segurança do host
  • 110.2 Lição 1
110.3 Proteção de dados com criptografia
  • 110.3 Lição 1
  • 110.3 Lição 2
How to get certified
  1. Tópico 105: Shells e scripts do Shell
  2. 105.2 Editar e escrever scripts simples
  3. 105.2 Lição 2

105.2 Lição 2

Certificação:

LPIC-1

Versão:

5.0

Tópico:

105 Shells e scripts do Shell

Objetivo:

105.2 Personalizar ou criar scripts simples

Lição:

2 de 2

Introdução

Os scripts de shell destinam-se geralmente a automatizar operações relacionadas a arquivos e diretórios — as mesmas operações que podem ser executadas manualmente na linha de comando. Porém, o alcance dos scripts de shell não se restringe apenas aos documentos do usuário, já que a configuração e interação com muitos aspectos de um sistema operacional Linux também são realizadas por meio de arquivos de script.

O shell Bash oferece muitos comandos internos úteis para criar scripts de shell, mas para aproveitar totalmente o poder desses scripts temos de combinar os comandos internos do Bash com os diversos utilitários de linha de comando disponíveis em um sistema Linux.

Testes ampliados

O Bash, como linguagem de script, é orientado sobretudo a arquivos, de forma que o comando interno do Bash test tem muitas opções para avaliar as propriedades dos objetos do sistema de arquivos (essencialmente arquivos e diretórios). Os testes que se concentram em arquivos e diretórios são úteis, por exemplo, para verificar se os arquivos e diretórios necessários para executar uma tarefa específica estão presentes e podem ser lidos. A seguir, associado a uma construção condicional if, o conjunto apropriado de ações é executado caso o teste seja bem-sucedido.

O comando test avalia as expressões usando duas sintaxes diferentes: as expressões de teste podem ser dadas como um argumento para o comando test ou podem ser postas entre colchetes, caso em que o comando test é dado implicitamente. Assim, o teste para avaliar se /etc é um diretório válido pode ser escrito como test -d /etc ou como [ -d /etc]:

$ test -d /etc
$ echo $?
0
$ [ -d /etc ]
$ echo $?
0

Como confirmam os códigos de status de saída na variável especial $? — um valor de 0 significa que o teste foi bem-sucedido — ambas as formas avaliaram /etc como um diretório válido. Supondo-se que o caminho para um arquivo ou diretório foi armazenado na variável $VAR, as seguintes expressões podem ser usadas como argumentos para test ou entre colchetes:

-a "$VAR"

Avalia se o caminho em VAR existe no sistema de arquivos e é um arquivo.

-b "$VAR"

Avalia se o caminho em VAR é um arquivo de bloco especial.

-c "$VAR"

Avalia se o caminho em VAR é um arquivo de caractere especial.

-d "$VAR"

Avalia se o caminho em VAR é um diretório.

-e "$VAR"

Avalia se o caminho em VAR existe no sistema de arquivos.

-f "$VAR"

Avalia se o caminho em VAR existe e é um arquivo regular.

-g "$VAR"

Avalia se o caminho em VAR tem permissão SGID.

-h "$VAR"

Avalia se o caminho em VAR é um link simbólico.

-L "$VAR"

Avalia se o caminho em VAR é um link simbólico (como -h).

-k "$VAR"

Avalia se o caminho em VAR tem a permissão sticky bit.

-p "$VAR"

Avalia se o caminho em VAR é um arquivo pipe.

-r "$VAR"

Avalia se o caminho em VAR é legível pelo usuário atual.

-s "$VAR"

Avalia se o caminho em VAR existe e não está vazio.

-S "$VAR"

Avalia se o caminho em VAR é um arquivo de socket.

-t "$VAR"

Avalia se o caminho em VAR está aberto em um terminal.

-u "$VAR"

Avalia se o caminho em VAR tem permissão SUID.

-w "$VAR"

Avalia se o caminho em VAR é gravável pelo usuário atual.

-x "$VAR"

Avalia se o caminho em VAR é executável pelo usuário atual.

-O "$VAR"

Avalia se o caminho em VAR é de propriedade do usuário atual.

-G "$VAR"

Avalia se o caminho em VAR pertence ao grupo efetivo do usuário atual.

-N "$VAR"

Avalia se o caminho em VAR foi modificado desde o último acesso.

"$VAR1" -nt "$VAR2"

Avalia se o caminho em VAR1 é mais recente que o caminho em VAR2, de acordo com as datas de modificação respectivas.

"$VAR1" -ot "$VAR2"

Avalia se o caminho em VAR1 é mais antigo que VAR2.

"$VAR1" -ef "$VAR2"

Esta expressão avalia como True (Verdadeiro) se o caminho em VAR1 é um link físico para VAR2.

Recomenda-se usar aspas duplas em torno de uma variável testada porque, se a variável por acaso estiver vazia, isso pode causar um erro de sintaxe para o comando test. As opções de teste requerem um argumento operando, e uma variável vazia sem aspas causaria um erro devido à falta de um argumento obrigatório. Também existem testes para variáveis de texto arbitrárias, descritos a seguir:

-z "$TXT"

Avalia se a variável TXT está vazia (tamanho zero).

-n "$TXT" or test "$TXT"

Avalia se a variável TXT não está vazia.

"$TXT1" = "$TXT2" or "$TXT1" == "$TXT2"

Avalia se TXT1 e TXT2 são iguais.

"$TXT1" != "$TXT2"

Avalia se TXT1 e TXT2 não são iguais.

"$TXT1" < "$TXT2"

Avalia se TXT1 vem antes de TXT2, em ordem alfabética.

"$TXT1" > "$TXT2"

Avalia se TXT1 vem depois de TXT2, em ordem alfabética.

Linguagens diferentes podem ter regras diferentes para a ordenação alfabética. Para obter resultados consistentes, independentemente das configurações de localização do sistema no qual o script está sendo executado, é recomendável definir a variável de ambiente LANG como C, como em LANG=C, antes de fazer operações que envolvam ordem alfabética. Essa definição também manterá as mensagens do sistema no idioma original e, portanto, deve ser usada apenas no escopo do script.

As comparações numéricas têm seu próprio conjunto de opções de teste:

$NUM1 -lt $NUM2

Avalia se NUM1 é menor que NUM2.

$NUM1 -gt $NUM2

Avalia se NUM1 é maior que NUM2.

$NUM1 -le $NUM2

Avalia se NUM1 é menor ou igual a NUM2.

$NUM1 -ge $NUM2

Avalia se NUM1 é maior ou igual a NUM2.

$NUM1 -eq $NUM2

Avalia se NUM1 é igual a NUM2.

$NUM1 -ne $NUM2

Avalia se NUM1 não é igual a NUM2.

Todos os testes podem receber os seguintes modificadores:

! EXPR

Avalia se a expressão EXPR é falsa.

EXPR1 -a EXPR2

Avalia se tanto EXPR1 quanto EXPR2 são verdadeiras.

EXPR1 -o EXPR2

Avalia se ao menos uma das duas expressões é verdadeira.

Outra construção condicional, case, pode ser vista como uma variação da construção if. A instrução case executa uma lista de comandos dados se um item especificado — por exemplo, o conteúdo de uma variável — puder ser encontrado em uma lista de itens separados por pipes (a barra vertical |) e encerrado por ). O exemplo de script a seguir mostra como a construção case pode ser usada para indicar o formato de pacote de software correspondente para uma determinada distribuição Linux:

#!/bin/bash

DISTRO=$1

echo -n "Distribution $DISTRO uses "
case "$DISTRO" in
	debian | ubuntu | mint)
    echo -n "the DEB"
  ;;
	centos | fedora | opensuse )
    echo -n "the RPM"
  ;;
	*)
    echo -n "an unknown"
  ;;
esac
echo " package format."

Cada lista de padrões e comandos associados deve terminar com ;;, ;&, ou ;;&. O último padrão, um asterisco, será usado se não for encontrada uma correspondência para nenhum outro padrão anterior. A instrução esac (case de trás pra frente) conclui a construção case. Supondo que o script de amostra anterior se chame script.sh e seja executado com opensuse como primeiro argumento, a seguinte saída será gerada:

$ ./script.sh opensuse
Distribution opensuse uses the RPM package format.
Tip

O Bash tem uma opção chamada nocasematch que ativa a correspondência de padrões sem distinção entre maiúsculas e minúsculas para a construção case e outros comandos condicionais. O comando interno shopt alterna os valores das configurações que controlam comportamentos opcionais do shell: shopt -s habilita (set) a opção fornecida e shopt -u desabilita (unset) a opção fornecida. Portanto, colocar shopt -s nocasematch antes da construção case permite encontrar padrões sem diferenciar maiúsculas de minúsculas. As opções modificadas por shopt afetarão apenas a sessão atual, de forma que as opções modificadas dentro de scripts em execução em um sub-shell — o que é a maneira padrão de executar um script — não afetarão as opções da sessão pai.

O item pesquisado e os padrões sofrem expansão de til, expansão de parâmetro, substituição de comando e expansão aritmética. Se o item pesquisado for especificado com aspas, elas serão removidas antes do script tentar encontrar uma correspondência.

Construções de loop

Os scripts são freqüentemente usados como ferramenta para automatizar tarefas repetitivas, executando o mesmo conjunto de comandos até que seja verificado um critério de interrupção. O Bash tem três instruções de loop — for, until e while — projetadas para construções de loop ligeiramente distintas.

A construção for percorre uma lista dada de itens — geralmente uma lista de palavras ou quaisquer outros segmentos de texto separados por espaços — executando o mesmo conjunto de comandos em cada um desses itens. Antes de cada iteração, a instrução for atribui o item atual a uma variável, que pode então ser usada pelos comandos incluídos. O processo é repetido até que não restem mais itens. A sintaxe da construção for é:

for VARNAME in LIST
do
	COMMANDS
done

VARNAME é um nome de variável arbitrária do shell e LIST é qualquer sequência de termos separados. Os caracteres delimitadores válidos que dividem os itens na lista são definidos pela variável de ambiente IFS, que são os caracteres espaço, tabulação e nova linha por padrão. A lista de comandos a serem executados é delimitada pelas instruções do e done, de modo que os comandos podem ocupar tantas linhas quantas forem necessárias.

No exemplo a seguir, o comando for pega cada item da lista fornecida — uma sequência de números — e os atribui à variável NUM, um de cada vez:

#!/bin/bash

for NUM in 1 1 2 3 5 8 13
do
	echo -n "$NUM is "
	if [ $(( $NUM % 2 )) -ne 0 ]
	then
		echo "odd."
	else
		echo "even."
  fi
done

No exemplo, uma construção aninhada if é usada em conjunto com uma expressão aritmética para avaliar se o número na variável NUM atual é par ou ímpar. Supondo-se que o script do exemplo anterior se chama script.sh e está no diretório atual, a seguinte saída será gerada:

$ ./script.sh
1 is odd.
1 is odd.
2 is even.
3 is odd.
5 is odd.
8 is even.
13 is odd.

O Bash também suporta um formato alternativo para construções for, com a notação de parênteses duplos. Essa notação se assemelha à sintaxe da instrução for da linguagem de programação C e é particularmente útil para trabalhar com matrizes:

#!/bin/bash

SEQ=( 1 1 2 3 5 8 13 )

for (( IDX = 0; IDX < ${#SEQ[*]}; IDX++ ))
do
	echo -n "${SEQ[$IDX]} is "
	if [ $(( ${SEQ[$IDX]} % 2 )) -ne 0 ]
	then
		echo "odd."
	else
		echo "even."
  fi
done

Este script gera exatamente a mesma saída do exemplo anterior. No entanto, em vez de usar a variável NUM para armazenar um item por vez, a variável IDX é empregada para rastrear o índice da matriz atual em ordem crescente, começando de 0 e continuando a adicionar enquanto esse número permanecer abaixo do número de itens na matriz SEQ. O item em si é recuperado de sua posição na matriz com ${SEQ[$IDX]}.

Da mesma forma, a construção until executa uma sequência de comandos até que um comando de teste — como o próprio comando test — seja encerrado com o status 0 (sucesso). Por exemplo, a mesma estrutura de loop do exemplo anterior pode ser implementada com until da seguinte forma:

#!/bin/bash

SEQ=( 1 1 2 3 5 8 13 )

IDX=0

until [ $IDX -eq ${#SEQ[*]} ]
do
	echo -n "${SEQ[$IDX]} is "
	if [ $(( ${SEQ[$IDX]} % 2 )) -ne 0 ]
	then
		echo "odd."
	else
		echo "even."
  fi
  IDX=$(( $IDX + 1 ))
done

As construções until podem exigir mais instruções do que as construções for, mas podem ser mais adequadas para critérios de parada não-numéricos fornecidos pelas expressões test ou qualquer outro comando. É importante incluir ações que garantam um critério de parada válido, como o incremento de uma variável de contador, caso contrário o loop pode acabar sendo executado indefinidamente.

A instrução while é semelhante à instrução until, mas while continua repetindo o conjunto de comandos se o comando de teste terminar com o status 0 (sucesso). Portanto, a instrução until [ $IDX -eq ${#SEQ[*]} ] do exemplo anterior é equivalente a while [ $IDX -lt ${#SEQ[*]} ], já que o loop deve ser repetido enquanto o índice da matriz for menor que o total de itens na matriz.

Um exemplo mais elaborado

Imagine que um usuário deseja sincronizar periodicamente uma coleção de seus arquivos e diretórios com outro dispositivo de armazenamento, montado em um ponto de montagem arbitrário no sistema de arquivos, e considera-se que um sistema de backup completo seria um exagero. Como esta é uma atividade que deve ser realizada periodicamente, trata-se de uma aplicação que vale a pena automatizar com um script de shell.

A tarefa é simples: sincronizar todos os arquivos e diretórios contidos em uma lista, de um diretório de origem informado como primeiro argumento do script para um diretório de destino informado como segundo argumento do script. Para ser mais fácil adicionar ou remover itens da lista, ela será mantida em um arquivo separado, ~/.sync.list, um item por linha:

$ cat ~/.sync.list
Documents
To do
Work
Family Album
.config
.ssh
.bash_profile
.vimrc

O arquivo contém uma mistura de arquivos e diretórios, alguns deles com espaços em branco em seus nomes. Este é um cenário adequado para o comando interno do Bash mapfile, que analisa qualquer conteúdo de texto dado e cria uma variável de matriz a partir dele, colocando cada linha como um item de matriz individual. O arquivo do script será denominado sync.sh e conterá o seguinte script:

#!/bin/bash

set -ef

# List of items to sync
FILE=~/.sync.list

# Origin directory
FROM=$1

# Destination directory
TO=$2

# Check if both directories are valid
if [ ! -d "$FROM" -o ! -d "$TO" ]
then
  echo Usage:
  echo "$0 <SOURCEDIR> <DESTDIR>"
  exit 1
fi

# Create array from file
mapfile -t LIST < $FILE

# Sync items
for (( IDX = 0; IDX < ${#LIST[*]}; IDX++ ))
do
	echo -e "$FROM/${LIST[$IDX]} \u2192 $TO/${LIST[$IDX]}";
	rsync -qa --delete "$FROM/${LIST[$IDX]}" "$TO";
done

A primeira ação realizada pelo script é redefinir dois parâmetros do shell com o comando set: a opção -e sai da execução imediatamente se um comando resultar em um status diferente de zero e a opção -f desabilita o globbing do nome do arquivo. Ambas as opções podem ser encurtadas como -ef. Esta não é uma etapa obrigatória, mas ajuda a diminuir a probabilidade de um comportamento inesperado.

As instruções reais do arquivo de script orientadas para a aplicação podem ser divididas em três partes:

  1. Coletar e verificar os parâmetros do script

    A variável FILE é o caminho para o arquivo que contém a lista de itens a serem copiados: ~/.sync.list. As variáveis FROM e TO são os caminhos de origem e destino, respectivamente. Como esses dois últimos parâmetros são fornecidos pelo usuário, eles passam por um teste de validação simples realizado pela construção if: se algum dos dois não for um diretório válido — determinado pelo teste [ ! -d "$FROM" -o ! -d "$TO" ] — o script mostrará uma breve mensagem de ajuda e se encerrará com um status de saída 1.

  2. Carregar lista de arquivos e diretórios

    Após todos os parâmetros serem definidos, uma matriz contendo a lista de itens a serem copiados é criada com o comando mapfile -t LIST < $FILE. A opção -t do mapfile remove o caractere final de nova linha de cada linha antes de incluí-lo na variável de matriz chamada LIST. O conteúdo do arquivo indicado pela variável FILE — ~/.sync.list — é lido via redirecionamento de entrada.

  3. Realizar a cópia e informar o usuário

    Um loop for usando a notação de parênteses duplo percorre a matriz de itens, com a variável IDX controlando o incremento do índice. O comando echo informa o usuário sobre cada item que está sendo copiado. O caractere Unicode de escape — \u2192 — para o caractere seta direita está presente na mensagem de saída, por isso opção -e do comando echo deve ser usada. O comando rsync copia seletivamente apenas as partes modificadas do arquivo de origem, portanto seu uso é recomendado para esse tipo de tarefa. As opções -q e -a do rsync, condensadas em -qa, inibem as mensagens do rsync e ativam o modo arquivar, no qual todas as propriedades do arquivo são preservadas. A opção --delete faz com que o rsync exclua um item do destino que não exista mais na origem e, portanto, deve ser usada com cuidado.

Supondo-se que todos os itens da lista existem no diretório inicial da usuária carol, /home/carol, e que o diretório de destino /media/carol/backup aponta para um dispositivo de armazenamento externo montado, o comando sync.sh /home/carol /media/carol/backup gera a seguinte saída:

$ sync.sh /home/carol /media/carol/backup
/home/carol/Documents → /media/carol/backup/Documents
/home/carol/"To do" → /media/carol/backup/"To do"
/home/carol/Work → /media/carol/backup/Work
/home/carol/"Family Album" → /media/carol/backup/"Family Album"
/home/carol/.config → /media/carol/backup/.config
/home/carol/.ssh → /media/carol/backup/.ssh
/home/carol/.bash_profile → /media/carol/backup/.bash_profile
/home/carol/.vimrc → /media/carol/backup/.vimrc

O exemplo também supõe que o script é executado pelo root ou pela usuária carol, já que a maioria dos arquivos seria ilegível por outros usuários. Se script.sh não estiver dentro de um diretório listado na variável de ambiente PATH, ele deve ser especificado com seu caminho completo.

Exercícios Guiados

  1. Como o comando test pode ser usado para verificar se o caminho do arquivo armazenado na variável FROM é mais recente do que um arquivo cujo caminho está armazenado na variável TO?

  2. O script a seguir deveria imprimir uma sequência numérica de 0 a 9 mas, em vez disso, imprime 0 eternamente. O que deve ser feito para se obter a saída esperada?

    #!/bin/bash
    
    COUNTER=0
    
    while [ $COUNTER -lt 10 ]
    do
      echo $COUNTER
    done
  3. Suponha que um usuário escreveu um script que requer uma lista ordenada de nomes de usuário. A lista resultante é apresentada da seguinte forma em seu computador:

    carol
    Dave
    emma
    Frank
    Grace
    henry

    No entanto, a mesma lista é ordenada assim no computador de seu colega:

    Dave
    Frank
    Grace
    carol
    emma
    henry

    O que poderia explicar as diferenças entre as duas listas ordenadas?

Exercícios Exploratórios

  1. Como todos os argumentos de linha de comando do script podem ser usados para inicializar uma matriz Bash?

  2. Porque é que, contraintuitivamente, o comando test 1 > 2 é avaliado como verdadeiro?

  3. Como um usuário poderia alterar temporariamente o separador de campo padrão apenas para o caractere de nova linha, sem deixar de ser capaz de revertê-lo ao conteúdo original?

Resumo

Esta lição discorre mais profundamente sobre os testes disponíveis para o comando test e outras construções condicionais e de loop, necessárias para escrever scripts de shell mais elaborados. Um script de sincronização de arquivo simples é fornecido como exemplo de aplicação prática para um script de shell. A lição trata dos seguintes tópicos:

  • Testes estendidos para as construções condicionais if e case.

  • Construções de loop do shell: for, until e while.

  • Iterações por meio de matrizes e parâmetros.

Os comandos e procedimentos abordados foram:

test

Realiza uma comparação entre os itens fornecidos ao comando.

if

Uma construção lógica usada em scripts para avaliar algo como verdadeiro ou falso e em seguida lançar a execução do comando com base nos resultados.

case

Avalia diversos valores em relação a uma única variável. A execução do comando do script é então realizada dependendo do resultado do comando case.

for

Repete a execução de um comando com base em um determinado critério.

until

Repete a execução de um comando até que uma expressão seja avaliada como falsa.

while

Repete a execução de um comando enquanto uma dada expressão for avaliada como verdadeira.

Respostas aos Exercícios Guiados

  1. Como o comando test pode ser usado para verificar se o caminho do arquivo armazenado na variável FROM é mais recente do que um arquivo cujo caminho está armazenado na variável TO?

    O comando test "$FROM" -nt "$TO" retorna um código de status 0 se o arquivo na variável FROM for mais recente que o arquivo na variável TO.

  2. O script a seguir deveria imprimir uma sequência numérica de 0 a 9 mas, em vez disso, imprime 0 eternamente. O que deve ser feito para se obter a saída esperada?

    #!/bin/bash
    
    COUNTER=0
    
    while [ $COUNTER -lt 10 ]
    do
      echo $COUNTER
    done

    A variável COUNTER deve ser incrementada, o que pode ser feito com a expressão aritmética COUNTER=$(( $COUNTER + 1 )), até atingir os critérios de parada e encerrar o loop.

  3. Suponha que um usuário escreveu um script que requer uma lista ordenada de nomes de usuário. A lista resultante é apresentada da seguinte forma em seu computador:

    carol
    Dave
    emma
    Frank
    Grace
    henry

    No entanto, a mesma lista é ordenada assim no computador de seu colega:

    Dave
    Frank
    Grace
    carol
    emma
    henry

    O que poderia explicar as diferenças entre as duas listas ordenadas?

    A classificação baseia-se na localidade (idioma) do sistema atual. Para evitar inconsistências, as tarefas de classificação devem ser realizadas com a variável de ambiente LANG definida como C.

Respostas aos Exercícios Exploratórios

  1. Como todos os argumentos de linha de comando do script podem ser usados para inicializar uma matriz Bash?

    Os comandos PARAMS=( $* ) ou PARAMS=( "$@" ) criam uma matriz chamada PARAMS com todos os argumentos.

  2. Porque é que, contraintuitivamente, o comando test 1 > 2 é avaliado como verdadeiro?

    O operador > deve ser usado com testes de string, e não testes numéricos.

  3. Como um usuário poderia alterar temporariamente o separador de campo padrão apenas para o caractere de nova linha, sem deixar de ser capaz de revertê-lo ao conteúdo original?

    Uma cópia da variável IFS pode ser armazenada em outra variável: OLDIFS=$IFS. Em seguida o novo separador de linhas é definido com IFS=$'\n' e a nova variável IFS pode ser revertida com IFS=$OLDIFS.

Linux Professional Insitute Inc. Todos os direitos reservados. Visite o site dos Materiais Didáticos: https://learning.lpi.org
31/5000 Este trabalho está licenciado sob a Licença Creative Commons Atribuição-Uso Não-Comercial-NãoDerivativos 4.0 Internacional.

Próxima Lição

106.1 Instalar e configurar o X11 (106.1 Lição 1)

Ir para a próxima lição

Linux Professional Insitute Inc. Todos os direitos reservados. Visite o site dos Materiais Didáticos: https://learning.lpi.org
31/5000 Este trabalho está licenciado sob a Licença Creative Commons Atribuição-Uso Não-Comercial-NãoDerivativos 4.0 Internacional.

A LPI é uma organização sem fins lucrativos.

© 2023 O Linux Professional Institute (LPI) é um organismo de apoio aos profissionais de Open Source e referência mundial em certificação. Com mais de 200.000 pessoas certificadas, somos o principal organismo de certificação independente para Linux e Open Source do mundo. O LPI certificou profissionais de mais de 180 países, oferece exames em diversos idiomas e tem centenas de parcerias de formação em todo o globo.

Nossa missão é proporcionar oportunidades econômicas e criativas para todos, tornando universalmente acessível a certificação de conhecimentos e competências em matéria de Open Source.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Entre em Contato
  • Política de Privacidade e Cookies

Encontrou um erro ou quer ajudar a aprimorar esta página? Escreva pra nós.

© 1999–2023 The Linux Professional Institute Inc. Todos os direitos reservados.