Programacao do Shell: mudanças entre as edições

De Wiki Cursos IFPR Foz
Ir para navegaçãoIr para pesquisar
 
(38 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 16: Linha 16:
  #!/bin/bash
  #!/bin/bash


Como todo programa, recomenda-se a inclusão de comentários para descrever a função do script e facilitar sua compreensão. Todo comentário inicia com o caractere '''#''', com exceção da linha de definição do Shell interpretador.
Dentro do programa um comentário inicia com o caractere '''#''', com exceção da linha de definição do Shell interpretador.


Exemplo de script que imprime uma frase <ref name=VALLE/>:
Exemplo de script que imprime uma frase <ref name=VALLE/>:
Linha 32: Linha 32:
===Variáveis e argumentos===
===Variáveis e argumentos===


O Shell possui várias '''variáveis internas''', como por exemplo $USER, $HOME, $SHELL, $PATH, etc.
;Variáveis internas do Shell: O Shell possui várias '''variáveis internas''', como por exemplo $USER, $HOME, $SHELL, $PATH, $PWD,etc.
Uma lista das variáveis internas do Shell pode ser obtida com o comando:
:Uma lista das variáveis internas do Shell pode ser obtida com o comando:
  printenv
  printenv


Linha 39: Linha 39:
  var="valor"
  var="valor"
:O valor pode ser uma frase, numero, comando ou outra variável.
:O valor pode ser uma frase, numero, comando ou outra variável.
:Não pode haver espaços entre a variável e o valor.
:O valor pode ser expressado entre as aspas (“ ”), apóstrofos (' ') ou crases (` `):
:O valor pode ser expressado entre as aspas (“ ”), apóstrofos (' ') ou crases (` `):
:*aspas (“ ”): interpretam as variáveis que estiverem dentro do valor;
:*aspas (“ ”): '''interpretam as variáveis''' que estiverem dentro do valor;
:*apóstrofos (' '): leem o valor literalmente, sem interpretar nada;
:*apóstrofos (' '): leem os valores '''literalmente''', sem interpretar nada;
:*crases (` `): interpretam um comando e retornar a sua saída para a variável.  
:*crases (` `): '''interpretam um comando''' e retornar a sua saída para a variável.  


Exemplos <ref>http://www.devin.com.br/shell_script/</ref>:
Exemplos <ref>http://www.devin.com.br/shell_script/</ref>:
  var="Eu sou o usuário $user"
  var="Eu sou o usuário $USER"
  echo $var
  echo $var
   
   
  Eu sou o usuário evandro
  Eu sou o usuário evandro


  var='Eu sou o usuário $user'
  var='Eu sou o usuário $USER'
  echo $var
  echo $var
   
   
  Eu sou o usuário $user
  Eu sou o usuário $USER


  var="Meu diretório atual é o `pwd`"
  var="Meu diretório atual é o `pwd`"
Linha 62: Linha 63:
;Variáveis passadas como argumentos: Um script pode manipular '''variáveis''' que recebem valor de '''argumentos''' passados quando o script é chamado.  
;Variáveis passadas como argumentos: Um script pode manipular '''variáveis''' que recebem valor de '''argumentos''' passados quando o script é chamado.  
:Internamente ao script, as seguintes variáveis são utilizadas:
:Internamente ao script, as seguintes variáveis são utilizadas:
*'$0' retorna o nome do script;
:*'$0' retorna o nome do script;
*'$1 a $9' retorna valor dos argumentos passados na chamada do script;
:*'$1 a $9' retorna valor dos argumentos passados na chamada do script;
*'$#' retorna o número de argumentos;
:*'$#' retorna o número de argumentos;
*'$*' retorna todos os argumentos.
:*'$*' retorna todos os argumentos.


Exemplo:
Exemplo:
Linha 78: Linha 79:
   echo "Usar 2 argumentos"
   echo "Usar 2 argumentos"
  fi
  fi
;Variáveis cujo valor é requisitado ao usuário pelo script: Como qualquer linguagem de programação o usuário pode ser solicitado a fornecer um valor, o qual será lido pela função '''read''' e armazenado em uma variável.
:Exemplo:
#!/bin/bash
#Este script requisita que o usuário digite um valor
echo -n "Por favor, digite seu nome: "
read nome
echo "Seu nome é $nome"
;Variável $?: Retorna o ''status'' do último comando executado:
*'''0''' em caso de '''sucesso'''
*un número diferente de zero caso contrário.
:Exemplo:
true
echo $?
0
false
echo $?
1
==Estruturas de controle==
;if: Implementa o clássico '''se-então-senão'''.
Exemplos:
#!/bin/bash
if [ $HOME = `pwd` ]
then
  echo "Você está no diretório home."
else
  echo "Você não está no diretório home"
fi
Veja a seguir os parâmetros mais comuns utilizados com o comando teste <ref>http://www.devmedia.com.br/introducao-ao-shell-script-no-linux/25778</ref>:
*'''n''' string1: o comprimento de string1 é diferente de 0;
*'''z''' string1: o comprimento de string1 é zero;
*string1 '''=''' string2: string1 e string2 são idênticas;
*string1 '''!=''' string2: string1 e string2 são diferentes;
*inteiro1 '''-eq''' inteiro2: inteiro1 possui o mesmo valor que inteiro2;
*inteiro1 '''-ne''' inteiro2: inteiro1 não possui o mesmo valor que inteiro2;
*inteiro1 '''-gt''' inteiro2: inteiro1 é maior que inteiro2;
*inteiro1 '''-ge''' inteiro2: inteiro1 é maior ou igual a inteiro2;
*inteiro1 '''-lt''' inteiro2: inteiro1 é menor que inteiro2;
*inteiro1 '''-le''' inteiro2: inteiro1 é menor ou igual a inteiro2;
*'''e''' nome_do_arquivo: verifica se nome_do_arquivo existe;
*'''d''' nome_do_arquivo: verifica se nome_do_arquivo é um diretório;
*'''f''' nome_do_arquivo: verifica se nome_do_arquivo é um arquivo regular (texto, imagem, programa, docs, planilhas).
;case: Implementa um '''se múltiplo'''.
Exemplo:
#!/bin/bash
echo -n "Digite um número: "
read num
case $num in
  1)
    echo "Número 1";
  ;;
  2)
    echo "Número 2";
  ;;
  *)
    echo "Não é número 1 nem 2";
  ;;
esac
;while e for: <ref>http://www.vivaolinux.com.br/artigo/Programacao-com-Shell-Script?pagina=2</ref>
#!/bin/bash
i=1;
while [ $i -le 10 ] ; do
  echo $i
  i=`expr $i + 1 `;
done
#!/bin/bash
for i in $( seq 10 ) ; do
  echo $i;
done
==Tarefa==
#Faça um script que liste o nome do usuário logado e imprima o seu diretório home.
#Faça um script que imprima a data no formato 04Nov2015 e imprima na sequência o conteúdo do diretório home.
#Faça um script que verifique se um usuário passado como parâmetro existe (sugestão: comando '''getent''': https://en.wikipedia.org/wiki/Getent).
#Faça um script que verifique se um grupo passado como parâmetro existe (sugestão: comando '''getent''').
#Faça um script que liste os membros de um grupo primário passado como parâmetro.
#Faça um script que liste os membros de um grupo secundário passado como parâmetro.
<!--===Resolução dos exercícios===
#!/bin/bash
#1 - Faça um script que liste o nome do usuário logado e imprima o seu diretório home.
echo "Olá, $USER! O seu diretório home é $HOME."
#LuisFelipe
#!/bin/bash
echo "Usuário logado: '$USER'"
echo "Diretório home: '$HOME'"
#Frederik
#!/bin/bash
#2 - Faça um script que imprima a data no formato 04Nov2015
      e imprima na sequencia o conteúdo do  diretório home.
clear
echo
echo -n "Data: "
date +%d%b%Y
echo
echo "Conteúdo do diretório home:"
sleep 1
echo
ls $HOME
echo
#LuisFelipe
;Testar se suário e grupo existem:
#! /bin/bash
if [ "$1" = "" ]; then
echo "Por favor, digite um usuário para verificação"
exit 0
else
if id -u "$1" > /dev/null 2>&1; then
echo "Usuário existe no sistema"
else
echo "Usuário não existe no sistema".
fi
fi
#Frederik
#!/bin/bash
if [ "$1" = "" ]; then
          echo "Por favor, digite um grupo para verificação"
exit 0
else
GROUP=`cat /etc/group|cut -d ":" -f1 | grep -w "$1"`
if `echo "$GROUP" | grep -q "$1"`; then
echo "Grupo existe no sistema"
else
echo "Grupo nao existe no sistema"
fi
fi
#Frederik
#!/bin/bash
echo -n "Informe o nome do grupo que deseja buscar: "
read grupo
if [ `cat /etc/group | grep -w -c $grupo` -gt 0 ]
then
echo "Grupo existe no sistema."
else
echo "Grupo não existe no sistema."
fi
#Clelionei
#!/bin/bash
#3 - Faça um script que verifique se um usuário passado como parâmetro existe
if [ $# -ne 1 ]
then
echo "Informe um e apenas 1 argumento."
exit 1
fi
USUARIO=`grep -o -P ^$1\\(?=:x\\) /etc/passwd`
if [ -z $USUARIO ]
then
echo "O usuário $1 não existe!"
else
echo "O usuário $1 existe!"
fi
#LuisFelipe
#!/bin/bash
#4 - Faça um script que verifique se um grupo passado como parâmetro existe
if [ $# -ne 1 ]
then
echo "Informe um e apenas 1 argumento."
exit 1
fi
GRUPO=`grep -o -P ^$1\\(?=:x\\) /etc/group`
if [ -z $GRUPO ]
then
echo "O grupo $1 não existe!"
else
echo "O grupo $1 existe!"
fi
#LuisFelipe
;Listar grupos primários
#!/bin/bash
c=1000
while [ `cat /etc/group | grep -w -c $c` -gt 0  ] ; do
echo `cat /etc/group | grep $c`
c=`expr $c + 1`
done
#Clelionei
Clelionei: Isto não lista todos os grupos, primários e secundários?
#!/bin/bash
echo "Usuários dos grupos primarios";
for groupid in `cat /etc/group | awk -F ":" '{ print $3}'`
do
cat /etc/passwd | awk -F ":" '{print $4":"$1}' | grep "$groupid:" | awk -F ":" '{print $2}'
done
#Frederik
#!/bin/bash
#5 - Faça um script que liste os grupos primários existentes no sistema.
# O comando a seguir traz os GID de todos os usuários
USUARIO=`grep -o -P 'x:\\d+:\K\\d+' /etc/passwd`
#echo $USUARIO  ##desmarque para ver o resultado
#O comando é primeiro composto como uma string.
COMANDO='grep -o -P ^.*(?=:x:('
#Em loop, cada GID eh concatenado à string COMANDO seguido pelo caracter '|', que indica uma uma alternacao, um OU logico.
for nome in $USUARIO
do
COMANDO="$COMANDO$nome|" ##neste script, as repeticoes nao sao tratadas.
done
#Finalmente, o arquivo contendo os Grupos eh especificado
COMANDO="$COMANDO$)) /etc/group" ##
#echo $COMANDO ##Desmarque para ver o comando completo
#Aqui, o resultado do comando COMANDO eh atribuido aa variavel LISTA
LISTA=`$COMANDO`
clear
echo 'Lista de Grupos Primários:'
echo
echo $LISTA
#LuisFelipe
Luis e Frederik: Pensei em listar somente os grupos primários vinculados aos usuários, sem os grupos de sistema (GID >= 1000).
;Listar grupos secundários:
#!/bin/bash
for GROUP in `cat /etc/group|cut -d ":" -f1`
do
cat /etc/group | grep  "^$GROUP:" | awk -F ":" '{ print $1}' | tr "," "\n";
done
#Frederik
#!/bin/bash
#6 - Faça um script que liste os grupos secundários existentes no sistema.
LISTA=`grep -o -P '^(.+)(?=:x.+\w+$)' /etc/group`
echo -n 'Lista de Grupos Secundários: '
echo $LISTA
#LuisFelipe
;Listar membros dos grupos primários:
#!/bin/bash
if [ "$1" = "" ]; then
        echo "Por favor, digite um grupo para verificação"
exit 0
else
GROUP=`cat /etc/group|cut -d ":" -f1 | grep -w "$1"`
if `echo "$GROUP" | grep -q "$1"`; then
groupid=`cat /etc/group | grep "^$GROUP:" | awk -F ":" '{ print $3}'`;
cat /etc/passwd | awk -F ":" '{print $4":"$1}' | grep "$groupid:" | awk -F ":" '{print $2}'
else
echo "Grupo nao existe no sistema"
fi
fi
#Frederik
#!/bin/bash
#7 - Faça um script que liste os membros do grupo primário passado como parâmetro.
if [ $# -ne 1 ]
then
echo "Informe um e apenas 1 argumento."
exit 1
fi
#O primeiro 'grep' retorna apenas o GID do grupo dado como parâmetro
COMANDO="grep -o -P ^$1:x:\K\d+ /etc/group"
#echo $COMANDO
#O resultado do comando eh guardado em uma variavel
GID=`$COMANDO`
#echo $GID
#Essa variavel eh usada para formar o segundo comando
COMANDO="grep -o -P ^.*(?=:x:\d+:$GID:) /etc/passwd"
#echo $COMANDO
LISTA=`$COMANDO`
echo -n "Membros Primários do grupo $1: "
echo $LISTA
#LuisFelipe
;Listar membros dos grupos primários:
#!/bin/bash
if [ "$1" = "" ]; then
        echo "Por favor, digite um grupo para verificação"
exit 0
else
GROUP=`cat /etc/group|cut -d ":" -f1 | grep -w "$1"`
if `echo "$GROUP" | grep -q "$1"`; then
cat /etc/group | grep  "^$GROUP:" | awk -F ":" '{ print $4}' | tr "," "\n";
else
echo "Grupo nao existe no sistema"
fi
fi
#Frederik
#!/bin/bash
#8 - Faça um script que liste os membros do grupo secundário passado como parâmetro.
if [ $# -ne 1 ]
then
echo "Informe um e apenas 1 argumento."
exit 1
fi
COMANDO="grep -o -P ^$1:x:\d+:\K.*$ /etc/group"
#echo $COMANDO
echo -n "Membros Secundários do grupo $1: "
$COMANDO
#LuisFelipe
-->


==Referências==
==Referências==
<references />
<references />


----
----usuário
--[[Usuário:Evandro.cantu|Evandro.cantu]] ([[Usuário Discussão:Evandro.cantu|discussão]]) 10h23min de 4 de novembro de 2015 (BRST)
--[[Usuário:Evandro.cantu|Evandro.cantu]] ([[Usuário Discussão:Evandro.cantu|discussão]]) 10h23min de 4 de novembro de 2015 (BRST)
----
----


[[Categoria:Administração de Servidores]]
[[Categoria:Administração de Servidores]]

Edição atual tal como às 16h36min de 19 de abril de 2021

Programação do Shell

A programação do Shell permite que o administrador crie pequenos programas para automatizar a administração do sistema, como por exemplo, uma sequência de comandos para realizar backup de dados.

Um programa Shell, ou script shell, é criado em um arquivo de texto contendo comandos do Linux, e pode incluir variáveis, realização de testes, laços de repetição, comentários, etc.

Um programa Shell é interpretado linha a linha pelo Shell, portanto, não é um programa a ser compilado [1].

Comandos básicos

Um script shell inicia com a definição de qual será o Shell interpretador do comando, por exemplo:

#!/bin/bash

Dentro do programa um comentário inicia com o caractere #, com exceção da linha de definição do Shell interpretador.

Exemplo de script que imprime uma frase [1]:

#!/bin/bash
#Este script imprime uma frase
echo "Alo $USER, bom dia!"
No exemplo é utilizada a variável $USER que retorna o nome do usuário.

O script deve ser salvo em um arquivo com a extensão .sh (exemplo: alo.sh) e deve ter permissão de execução:

chmod +x alo.sh

Para executá-lo, chamar pelo nome do arquivo, por exemplo:

./alo.sh

Variáveis e argumentos

Variáveis internas do Shell
O Shell possui várias variáveis internas, como por exemplo $USER, $HOME, $SHELL, $PATH, $PWD,etc.
Uma lista das variáveis internas do Shell pode ser obtida com o comando:
printenv
Variáveis definidas pelo usuário
O usuário pode definir variáveis dentro de um script e associar valores a elas, por exemplo:
var="valor"
O valor pode ser uma frase, numero, comando ou outra variável.
Não pode haver espaços entre a variável e o valor.
O valor pode ser expressado entre as aspas (“ ”), apóstrofos (' ') ou crases (` `):
  • aspas (“ ”): interpretam as variáveis que estiverem dentro do valor;
  • apóstrofos (' '): leem os valores literalmente, sem interpretar nada;
  • crases (` `): interpretam um comando e retornar a sua saída para a variável.

Exemplos [2]:

var="Eu sou o usuário $USER"
echo $var

Eu sou o usuário evandro
var='Eu sou o usuário $USER'
echo $var

Eu sou o usuário $USER
var="Meu diretório atual é o `pwd`"
echo $var

Meu diretório atual é o /home/evandro
Variáveis passadas como argumentos
Um script pode manipular variáveis que recebem valor de argumentos passados quando o script é chamado.
Internamente ao script, as seguintes variáveis são utilizadas:
  • '$0' retorna o nome do script;
  • '$1 a $9' retorna valor dos argumentos passados na chamada do script;
  • '$#' retorna o número de argumentos;
  • '$*' retorna todos os argumentos.

Exemplo:

#!/bin/bash
#Este script verifica se há dois argumentos
#e realiza a soma dos mesmos
if [ $# -eq 2 ]
then
  soma=`expr $1 + $2`
  echo "Soma = $soma" 
else
  echo "Usar 2 argumentos"
fi
Variáveis cujo valor é requisitado ao usuário pelo script
Como qualquer linguagem de programação o usuário pode ser solicitado a fornecer um valor, o qual será lido pela função read e armazenado em uma variável.
Exemplo:
#!/bin/bash
#Este script requisita que o usuário digite um valor
echo -n "Por favor, digite seu nome: "
read nome
echo "Seu nome é $nome"
Variável $?
Retorna o status do último comando executado:
  • 0 em caso de sucesso
  • un número diferente de zero caso contrário.
Exemplo:
true
echo $?
0
false
echo $?
1

Estruturas de controle

if
Implementa o clássico se-então-senão.

Exemplos:

#!/bin/bash
if [ $HOME = `pwd` ]
then
  echo "Você está no diretório home."
else
  echo "Você não está no diretório home"
fi

Veja a seguir os parâmetros mais comuns utilizados com o comando teste [3]:

  • n string1: o comprimento de string1 é diferente de 0;
  • z string1: o comprimento de string1 é zero;
  • string1 = string2: string1 e string2 são idênticas;
  • string1 != string2: string1 e string2 são diferentes;
  • inteiro1 -eq inteiro2: inteiro1 possui o mesmo valor que inteiro2;
  • inteiro1 -ne inteiro2: inteiro1 não possui o mesmo valor que inteiro2;
  • inteiro1 -gt inteiro2: inteiro1 é maior que inteiro2;
  • inteiro1 -ge inteiro2: inteiro1 é maior ou igual a inteiro2;
  • inteiro1 -lt inteiro2: inteiro1 é menor que inteiro2;
  • inteiro1 -le inteiro2: inteiro1 é menor ou igual a inteiro2;
  • e nome_do_arquivo: verifica se nome_do_arquivo existe;
  • d nome_do_arquivo: verifica se nome_do_arquivo é um diretório;
  • f nome_do_arquivo: verifica se nome_do_arquivo é um arquivo regular (texto, imagem, programa, docs, planilhas).
case
Implementa um se múltiplo.

Exemplo:

#!/bin/bash
echo -n "Digite um número: "
read num
case $num in
 1)
    echo "Número 1";
 ;;
 2)
    echo "Número 2";
 ;;
 *)
    echo "Não é número 1 nem 2";
 ;;
esac
while e for
[4]
#!/bin/bash
i=1;
while [ $i -le 10 ] ; do 
  echo $i
  i=`expr $i + 1 `;
done
#!/bin/bash
for i in $( seq 10 ) ; do
  echo $i;
done

Tarefa

  1. Faça um script que liste o nome do usuário logado e imprima o seu diretório home.
  2. Faça um script que imprima a data no formato 04Nov2015 e imprima na sequência o conteúdo do diretório home.
  3. Faça um script que verifique se um usuário passado como parâmetro existe (sugestão: comando getent: https://en.wikipedia.org/wiki/Getent).
  4. Faça um script que verifique se um grupo passado como parâmetro existe (sugestão: comando getent).
  5. Faça um script que liste os membros de um grupo primário passado como parâmetro.
  6. Faça um script que liste os membros de um grupo secundário passado como parâmetro.


Referências


usuário

--Evandro.cantu (discussão) 10h23min de 4 de novembro de 2015 (BRST)