Opa, hoje vamos ver um comando bem interessante e que eu adotei uma tarefa bem legal para ele, o comando source.
Não sei se a maioria que segue meu blog é familiarizado com Linux e scripts mas principalmente quem “desenvolve” usando a plataforma Linux, que seja para embarcados, linux, compilação-cruzada tenho certeza que já usaram o source se não usaram vai mudar de ideia depois deste post.
Imagine que você instalou um toolchain (todas as ferramentas necessárias para você compilar um código .c para um ARM Cortex-M3, por exemplo :), só que esta diferente do seu PATH e pior tem variáveis que possuem instruções e parâmetros que devem ser carregadas, ae só adicionar a linha dos bin no PATH não adianta. Ok, adiciono as variáveis no .bashrc fecho e abro novamente e boa, só que é ae que entra o source e resolve nossa vida.
Sintaxe do comando:
source arquivo source arquivo.sh
Agora vamos ao exemplo pratico1.sh:
cleiton@linuxVM:~/projetos/shell script/source$ touch pratica1.sh pratica1.conf cleiton@linuxVM:~/projetos/shell script/source$ vim pratica1.conf NOME="proc_hardening.sh" DESC="SET RULES KERNEL IN /PROC" USERS_LIB="cleiton root admin" PORTS_TCP="80 22 53" PORTS_UDP="53 161" cleiton@linuxVM:~/projetos/shell script/source$ vim pratica1.sh #!/bin/bash source pratica1.conf echo "Nome script: " $NOME echo "Descricao: " $DESC echo "Portas TCP para o firewall liberar:" $PORTS_TCP echo "Portas UDP para o firewall liberar:" $PORTS_UDP
Saída:
cleiton@linuxVM:~/projetos/shell script/source$ ./pratica1.sh Nome script: proc_hardening.sh Descricao: SET RULES KERNEL IN /PROC Portas TCP para o firewall liberar: 80 22 53 Portas UDP para o firewall liberar: 53 161
No nosso caso eu criei o script pratica1.sh e um arquivo com suposta configuração pratica1.conf, ele poderia ser somente-leitura a permissão e o source irá ler ele todo, e como tenho atribuições a nomes ele torna essas variáveis acessíveis no pratica1.sh após chamá-los, voltando no .bashrc, eu poderia adicionar qualquer coisa la e executar source ~/.bashrc que ele seria recarregado, posso fazer isso com qualquer arquivo até mesmo outro script, vamos ver o pratica2.sh:
cleiton@linuxVM:~/projetos/shell script/source$ vim rotinas_default.sh #!/bin/bash touch log_tmp.log OUTPUT_FS=$(cat /proc/filesystems) cleiton@linuxVM:~/projetos/shell script/source$ vim pratica2.sh #!/bin/bash source rotinas_default.sh # Verificando se o arquivo pratica1.conf exite # Caso nao existir || ira imprimir a mensagem em echo, remover o arquivo que foi # criado em rotinas_default.sh e sair do script [ -e pratica11.conf ] || { echo "Arquivo pratica1.conf ausente!"; rm log_tmp.log; exit 0; } source pratica1.conf echo "Bloqueando todas as portas e protocolos..." echo for porta in ${PORTS_UDP[@]} do echo "Liberando acesso UDP a porta $porta" done echo for porta in ${PORTS_TCP[@]} do echo "Liberando acesso TCP a porta $porta" done echo echo "FileSystems carregados..." echo $OUTPUT_FS rm log_tmp.log
cleiton@linuxVM:~/projetos/shell script/source$ ./pratica2.sh Bloqueando todas as portas e protocolos... Liberando acesso UDP a porta 53 Liberando acesso UDP a porta 161 Liberando acesso TCP a porta 80 Liberando acesso TCP a porta 22 Liberando acesso TCP a porta 53 FileSystems carregados... nodev sysfs nodev rootfs nodev bdev nodev proc nodev cgroup nodev cpuset nodev tmpfs nodev devtmpfs nodev debugfs nodev securityfs nodev sockfs nodev pipefs nodev anon_inodefs nodev devpts ext3 ext4 nodev ramfs nodev hugetlbfs nodev ecryptfs fuseblk nodev fuse nodev fusectl nodev pstore nodev mqueue nodev binfmt_misc
Agora se eu mudar o nome do .conf:
cleiton@linuxVM:~/projetos/shell script/source$ mv pratica1.conf pratica1.old cleiton@linuxVM:~/projetos/shell script/source$ ls -l total 16 -rw-r--r-- 1 cleiton cleiton 0 May 12 21:30 log_tmp.log -r--r--r-- 1 cleiton cleiton 125 May 12 20:12 pratica1.old -rwxr-xr-x 1 cleiton cleiton 272 May 12 20:11 pratica1.sh -rwxr-xr-x 1 cleiton cleiton 611 May 12 21:30 pratica2.sh -rwxr-xr-x 1 cleiton cleiton 66 May 12 20:19 rotinas_default.sh cleiton@linuxVM:~/projetos/shell script/source$ ./pratica2.sh Arquivo pratica1.conf ausente! cleiton@linuxVM:~/projetos/shell script/source$
Bom, se com um script eu chamando com source ele executa gera o mesmo efeito que ./pratica2.sh, certo? Sim, correto tanto que no nosso script rotinas_default.sh que é chamado eu crio um arquivo no diretório local e dou um cat em /proc/filesystems. E se executar como . pratica2.sh irá aplicar o exit 0 por exemplo no terminal corrente finalizando o mesmo, porém para ler um arquivo como nosso pratica1.conf ae é com o source.
Eu particularmente uso muito o source aplicando a mesma ideia do post, crio varias variáveis chaves do script como PORTAS_UDP, PORTAS_TCP que são arrays em um arquivo .conf ou sem extensão mesmo que por fim é chamado no script principal e algumas estruturas de repetição trata essas informações.
Acho que fica bem organizado e legal para quem for mexer ou dar manutenção, gostaram do uso do source?
Como exercício, use o USERS_LIB que deixei no pratica1.conf para fazer algo baseado no usuário logado por exemplo ou o grupo :), boa sorte!
Até a próxima!
Referência
http://bash.cyberciti.biz/guide/Source_command
Shell Script – Source by Cleiton Bueno is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.