Este tutorial foi apresentado no Grupy-SP em Agosto de 2016.
Todo material também está disponível em http://grandeportal.github.io/
http://grandeportal.github.io/shell/2016/shell-script1/
http://grandeportal.github.io/shell/2016/shell-script2/
http://grandeportal.github.io/shell/2016/shell-script3/
http://grandeportal.github.io/shell/2016/shell-script-python/
Você já leu o Papo de Botequim por Julio Cezar Neves? Se não, eu sugiro que leia, pois é um excelente material sobre Shell Script. Lá ele explica, dentre outras coisas, a diferença entre Bash e Shell. Bom, aqui eu vou mostrar apenas os comandos que eu considero mais relevantes, mas não deixe de ler o Papo de Botequim.
Bash é o interpretador e Shell Script é a linguagem.
O Canivete Suíço do Shell (Bash) do Aurélio Marinho Jargas é o guia de referência de quem quer aprender Shell Script. E por isso vou reproduzir aqui os comandos que ele menciona em "A caixa de ferramentas do shelleiro".
Comando | Função | Opções úteis |
---|---|---|
cat | Mostra arquivo | -n, -s |
cut | Extrai campo | -d -f, -c |
date | Mostra data | -d, +'...' |
diff | Compara arquivos | -u, -Nr, -i, -w |
echo | Mostra texto | -e, -n |
find | Encontra arquivos | -name, -iname, -type f, -exec, -or |
fmt | Formata parágrafo | -w, -u |
grep | Encontra texto | -i, -v, -r, -qs, -n, -l, -w -x, -A -B -C |
head | Mostra início | -n, -c |
od | Mostra caracteres | -a, -c, -o, -x |
paste | Paraleliza arquivos | -d, -s |
printf | Mostra texto | nenhuma |
rev | Inverte texto | nenhuma |
pwd | Mostra o caminho do diretório atual | |
sed | Edita texto | -n, -f, s/isso/aquilo/, p, d, q, N |
seq | Conta números | -s, -f |
sort | Ordena texto | -n, -f, -r, -k -t, -o |
tac | Inverte arquivo | nenhuma |
tail | Mostra final | -n, -c, -f |
tee | Arquiva fluxo | -a |
tr | Transforma texto | -d, -s, A-Z a-z |
top | Mostra os processos dinamicamente | |
uniq | Remove duplicatas | -i, -d, -u |
wc | Conta letras | -c, -w, -l, -L |
which | Mostra a localização de um arquivo executável | |
who | Mostra que está conectado | |
whoami | Mostra o nome do usuário logado | |
xargs | Gerencia argumentos | -n, -i |
Antes de sair explorando "A caixa de ferramentas do shelleiro", vamos começar do começo.
Para abrir o terminal você pode pressionar Ctrl+Alt+T.
O $
é o prompt do comando, ou seja, a partir deste símbolo você pode digitar seus comandos.
Se você já leu alterando o prompt terminal você deve ter visto este prompt:
rg3915@acer:~/gh/grandeportal$
onde
usuario@maquina:caminho$
E ~
é a pasta principal, a pasta home
do usuário atual.
Esta é a configuração padrão do prompt de comando do terminal, mas se quiser, você pode mudar digitando, por exemplo.
PS1="$ "
Para todos os comandos digite
--help
.
$ <comando> --help
$ pwd
Mostra o nome e caminho do diretório atual.
$ mkdir pastaprincipal
$ mkdir pasta1 pasta2 pasta3
$ mkdir -p novapasta/subpasta
O argumento -p
cria os diretórios pais à medida que forem necessários sem gerar erro. Ou seja, para criar subpasta primeiro ele cria novapasta.
$ rmdir pastaprincipal
Remove o diretório se estiver vazio.
$ touch arquivoprincipal.txt
$ touch arquivo1.txt arquivo2.txt arquivo3.txt
$ touch templates/{base.html,index.html,nav.html}
Obs: Note que neste exemplo devemos criar a pasta templates antes.
$ ls
$ ls -l
$ ls -la
$ ls
arquivo1.txt arquivo2.txt arquivo3.txt arquivoprincipal.txt
-l
esta opção usa o formato de listagem longa.
$ ls -l
total 16
-rw-rw-r-- 1 rg3915 rg3915 0 Mar 5 10:57 arquivo1.txt
-rw-rw-r-- 1 rg3915 rg3915 0 Mar 5 10:57 arquivo2.txt
-rw-rw-r-- 1 rg3915 rg3915 0 Mar 5 10:57 arquivo3.txt
-rw-rw-r-- 1 rg3915 rg3915 0 Mar 5 10:57 arquivoprincipal.txt
-a
mostra arquivos ocultos, que começam com .
$ ls -la
total 32
drwxrwxr-x 2 rg3915 rg3915 4096 Mar 5 10:57 .
drwxrwxr-x 3 rg3915 rg3915 4096 Mar 5 10:57 ..
-rw-rw-r-- 1 rg3915 rg3915 0 Mar 5 10:57 .env
-rw-rw-r-- 1 rg3915 rg3915 0 Mar 5 10:57 arquivo1.txt
-rw-rw-r-- 1 rg3915 rg3915 0 Mar 5 10:57 arquivo2.txt
-rw-rw-r-- 1 rg3915 rg3915 0 Mar 5 10:57 arquivo3.txt
-rw-rw-r-- 1 rg3915 rg3915 0 Mar 5 10:57 arquivoprincipal.txt
No exemplo, .env
é um arquivo oculto.
Experimente
$ ls -lh
$ sudo apt-get install tree
$ tree templates
$ tree --help
Depois de ler os comandos a seguir você vai entender o que o maluco fez quando excluiu todos os dados da empresa.
$ rm arquivoprincipal.txt
$ rm -i arquivoprincipal.txt
$ rm -f arquivoprincipal.txt
$ rm -rf novapasta
$ rm arquivo*.txt
$ rm *.txt
Cuidado: os comandos a seguir são extremamente perigosos!!!
$ rm *
$ rm -rf *
Cuidado: O primeiro comando exclui todos os arquivos da pasta atual. O segundo exclui todos recursivamente e com force ativado, ou seja, exclui arquivos não-vazios sem perguntar.
Experimente
$ rm -rf \*
Este comando anula o efeito excluir tudo.
Leia mais em cuidado com comandos perigosos do shell.
cp arquivo.txt arquivo_bkp.txt
cp arquivo.txt /subpasta
cp * /subpasta
cp ~/Documentos .
cp -R ~/Documentos backup/
Move ou renomeia arquivos e diretórios. Semelhante ao cp
, mas o arquivo de origem é apagado.
$ mv arquivo.txt backup/
$ mv arquivo.txt novo_nome.txt
O comando a seguir cria um link simbólico, o que comumente chamamos de atalho.
$ ln -s ~/Imagens/ img
Digitando cd img
entramos na pasta ~/Imagens/
através do atalho.
Redireciona a saída de um comando para outro arquivo. Se o arquivo existir será sobrescrito.
$ ls -la > dir.txt
Redireciona a saída, mas acrescentando os dados ao final do arquivo, sem sobrescrever o arquivo.
ls /etc/passwd >> dir.txt
Redireciona a entrada.
wc -l < arquivo
Conta o número de linhas não vazias do arquivo.
Experimente:
cat << EOF > arquivo.txt
Z
X
C
B
A
EOF
Depois
cat arquivo.txt
Depois
sort < arquivo.txt
Pipes ( |
barra vertical) - permite que um programa utilize como entrada a saída de outro programa.
$ ls | wc -l
$ echo Existem `who | wc -l` usuarios conectados
$ ls -a | sort -r
Faz com que o comando sort
receba como entrada a saída produzida pelo comando ls
. Neste exemplo o sort
ordena na ordem reversa.
$ cat /etc/passwd | wc -l > lista.txt
Grava no arquivo lista.txt
o número de linhas do arquivo passwd
.
Pesquisando em um arquivo específico.
$ grep force_color ~/.bashrc
Resultado:
force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
unset color_prompt force_color_prompt
Pesquisando em todos os arquivos do tipo txt
.
$ grep regis *.txt
Pesquisando na saída de um comando
$ who | grep rg3915
$ ps aux | grep python
$ curl http://www.meetup.com/pt-BR/Grupy-SP/events/232869373/ | grep Regis
$ curl http://www.meetup.com/pt-BR/Grupy-SP/events/232869373/ | grep -c Python
$ grep -i
$ grep --ignore-case
$ grep -r
$ grep --recursive
$ grep -c
$ grep --count
echo "Hello World"
Experimente
echo {2..10}
echo {a..Z}
echo azul{' claro',' escuro'}
printf "Um\tDois"
printf "Um\nDois"
Não vou explicar muito, apenas digite e veja o que acontece ;)
seq 10
seq 2 2 10
mkdir pasta; touch pasta/arquivo.txt; cd pasta; ls
if grep mm /etc/passwd; then echo 'ok'; else echo 'não'; fi
if who | grep regis; then echo regis está logado; else echo regis não está logado; fi
A seguir, usaremos o comando test
para verificar se um arquivo existe.
# Verifica se o arquivo existe
if test -e $1; then cat $1; else echo Arquivo não encontrado; fi
Repare, no exemplo a seguir, que podemos substituir o comando test
por um par de colchetes [ ]
.
# Verifica se uma pasta existe
if [ ! -d pasta42 ]; then echo 'Pasta não existe'; else echo 'Pasta já existe, veja:'; ls; fi
n1=1
n2=2
if [ $n1 -eq $n2 ]
then
echo "n1 é igual a n2"
else
echo "n1 é diferente de n2"
fi
n1=1
n2=2
if [ $n1 -ne $n2 ]
then
echo "n1 é diferente de n2"
else
echo "n1 é igual a n2"
fi
c=0; while [[ c -le 10 ]]; do echo "$c"; (( c++ )); sleep 0.5; done
#!/bin/bash
c=0
a=1
b=1
read -p "Enter limit of fibonacci Series:" n
echo -n "$a "
echo -n "$b "
#Fibonacci series logic
while((c<n))
do
c=$((a+b))
echo -n "$c "
a=$b
b=$c
done
echo -e "\n"
$((a+b))
significa uma expansão aritmética.
for i in $(seq 10); do echo "$i"; sleep 0.5; done
itens="Um Dois Três Quatro Cinco"
for item in $itens; do echo $item; done
for ((i=1; i<=9; i++))
do
echo -n "$i "
done
echo ""
for i in $(seq 10); do touch file$i.txt; done
read -p "Digite seu nome: " nome; echo "Bem-vindo $nome"
#!/bin/bash
soma(){
a=$1
b=$2
echo `expr $a + $b`
}
read -p 'Digite um número: ' x
read -p 'Digite outro número: ' y
soma $x $y
$ sudo apt-get install gpw
for i in $(seq 1 10); do echo "text$i" > file$i.txt; gpw 7 10 >> file$i.txt; done
for i in $(seq 1 10); do cat file$i.txt >> finalfile.txt; done
echo "Um" > um.txt
echo "Dois" > dois.txt
arqs="um.txt dois.txt"
for i in $arqs; do cat $i >> joinedfile.txt; done
arqs="um.txt dois.txt"
cat $arqs > joinedfile.txt
cat joinedfile.txt
printf '%s\n' 'Um' 'Dois' 'Três' 'Quatro' 'Cinco' > file.txt
# ou
itens="Um Dois Três Quatro Cinco"; for item in $itens; do echo $item >> file.txt; done
# Separando
while read line; do line=${line}; echo "${line}" > "${line}"; done < file.txt
# Lendo
while read line; do cat "${line}"; done < file.txt
SECRET_KEY=apqoie38728cmx8s67xs
ALLOW_HOST=127.0.0.1
$ cat SECRET_KEY
apqoie38728cmx8s67xs
$ cat ALLOW_HOST
127.0.0.1
echo "Eu gosto de Java." > linguagens.txt
cat linguagens.txt
sed -i "s/Java/Python/g" linguagens.txt
cat linguagens.txt
# Criando 30 arquivos com nomes aleatórios
for i in $(seq 1 30); do var=`gpw 1 10`; touch $var.txt; done
# Renomenando tudo numericamente
c=0; j=1; for i in *; do ((c++)); if (($c <= 9)); then mv $i 0$j\_$i; else mv $i $j\_$i; fi; ((j++)); done
sed -n "/pattern/{=;p}" arquivo
sed -n "/*/{=;p}" arquivo.txt | sed "{N;s/\n/ /}" > arquivo2.txt
cat -n arquivo.txt > arquivo2.txt
awk '{printf("%5d: %s\n", NR,$0)}' arquivo.txt > arquivo2.txt
PS1="$ "
PS1="\e[1;34m/\W\e[00m$ "
http://grandeportal.github.io/terminal/2016/alterando-o-prompt-do-terminal/
vim ~/.bash_profile
alias rm='rm -i'
vim ~/.bashrc
source ~/.bash_profile
http://grandeportal.github.io/terminal,%20alias/2016/renomeando-comandos/
#!/bin/bash
#Taking input
read -p "Enter Number:" number
#Outer loop for printing number of rows in pyramid
for((row=1;row<=number;row++))
do
#Loop for printing required spaces
for((spaces=row;spaces<=number;spaces++))
do
echo -ne " "
done
#Loop for printing 1st part
for((j=1;j<=row;j++))
do
echo -ne "$j"
done
#Loop for printing 2nd part
for((l=(row-1);l>=1;l--))
do
echo -ne "$l"
done
#echo for printing new line
echo
done
http://technicalworldforyou.blogspot.com.br/2014/01/shell-script-to-print-pyramid-of-numbers.html
import subprocess
subprocess.call("clear", shell=True)
subprocess.call("echo 'Usando Shell Script e Python'", shell=True)
subprocess.call("ls -l", shell=True)
https://docs.python.org/3/library/subprocess.html
http://www.jperla.com/blog/post/a-clean-python-shell-script
sl
cmatrix
figlet Grupy-SP
sudo apt-get install libaa-bin
aafire
sudo apt-get install bsdgames
worm
Leia mais em
http://technicalworldforyou.blogspot.com.br/
http://rberaldo.com.br/curso-de-shell-script-modulo-1-scripts-shell-estruturas/
http://aurelio.net/shell/canivete/
https://pt.wikipedia.org/wiki/Bash
http://aurelio.net/shell/canivete/#ferramentas
https://jneves.wordpress.com/2008/03/05/papo-de-botequim-parte-1/
http://wiki.softwarelivre.org/TWikiBar/WebHome
http://grandeportal.github.io/
http://grandeportal.github.io/shell/2016/shell-script1/
http://grandeportal.github.io/shell/2016/shell-script2/
http://grandeportal.github.io/shell/2016/shell-script3/
http://grandeportal.github.io/shell/2016/shell-script-python/