Como faço para que o ~ / .bashrc execute todos os scripts no meu diretório ~ / Shell usando um loop?

4

Eu tenho scripts de shell no meu diretório ~/Shell que eu quero que sejam executados sempre que o Bash for iniciado como minha conta de usuário usual. Então, o que eu fiz foi adicionar o seguinte a ~/.bashrc :

for i in 'find ~/Shell/ -name "*.sh"'
do
    sh $i
done

mas, por qualquer motivo, as funções contidas nos arquivos com a extensão de arquivo .sh no meu diretório ~/Shell não são carregadas automaticamente. Por exemplo, eu tenho uma função chamada abash no meu arquivo ~/Shell/bash.sh e executar abash de um novo terminal de usuário deu um erro informando que o comando não foi encontrado.

Eu sei que posso listar manualmente todos os arquivos no meu diretório ~/Shell com um ponto antes deles para executá-los no tempo de inicialização do Bash. Por exemplo, eu costumava ter isso no meu arquivo ~/.bashrc :

. ~/Shell/bash.sh
. ~/Shell/cd.sh
. ~/Shell/emerge.sh
...

e funcionou bem, mas eu preferiria um for loop para fazer isso, pois isso significaria que se eu adicionasse novos scripts de shell a ~/Shell eu não teria que me preocupar em adicioná-los a ~/.bashrc .

Eu também já tentei:

for i in 'find -name "~/Shell/*.sh"'
do
        sh $i
done

e:

for i in "~/Shell/*.sh"
do
        sh $i
done

e:

for i in 'find -name '~/Shell/*.sh''
do
        sh $i
done

sem sucesso.

    
por Brenton Horne 31.10.2015 / 03:13

2 respostas

3

Coloque isso no seu .bashrc :

for rc in ~/Shell/*.sh
do
    . "$rc"
done

E você está fora das corridas!

Algumas notas:

O comando bash (e zsh etc) source , embora legível, não é universal e não existe em dash , o shell mais posixly correto que eu conheço. Tal como está, este mesmo código pode ser usado para carregar código em quase qualquer derivado de shell de bourson.

A convenção de nomenclatura tradicional para arquivos a serem originados diretamente no shell é usar um sufixo de rc ou .rc (como em .bashrc ). rc significa "comandos de execução". A extensão .sh é geralmente usada para programas de script executáveis. (Estas são as convenções somente - não as regras.)

    
por 31.10.2015 / 03:52
1

Várias questões:

  • Para funcionar, o til precisa ser desatualizado. Use $ HOME, em vez disso.
  • Para funcionar, o * também precisa ser desmarcado. Não é necessário para encontrar.
  • NÃO deve haver / em nomes de arquivos ("~ / Shell /") para localizar.
  • Como os arquivos precisam ser carregados e não executados, sh deve ser alterado para a origem.

Tente isto:

for i in $(find "$HOME/Shell/" -iname "*.sh")
do 
    source "$i"
done

EDITAR:

A opção acima não pôde processar nomes de arquivos com espaços, novas linhas ou caracteres problemáticos. Para resolver isso, podemos usar as capacidades completas de encontrar, como isto:

while IFS= read -r -d $'
resetextglob=$(shopt -p extglob)     # store value of extglob
resetnullglob=$(shopt -p nullglob)   # store value of nullglob

shopt +s extglob nullglob
for i in $HOME/Shell/*.sh $HOME/Shell/**/*.sh
do
    source "$i"
done

$resetextglob                        # reset extglob to original value
$resetnullglob                       # reset nullglob to original value
' file; do source "$file" done < <(find "$HOME/Shell/" -name "*.sh" -type f -print0)

NOTA:

Uma solução com um asterisco simples * não incluirá subdiretórios.

Uma solução completa usando asteriscos que incluirão subdiretórios da mesma maneira que encontrar parece muito complexa:

for i in $(find "$HOME/Shell/" -iname "*.sh")
do 
    source "$i"
done
    
por 31.10.2015 / 03:37