Estratégia para esquecer de executar um script com 'source'?

0

Eu gostaria de escrever um script para acessar o estado de um shell bash interativo, por exemplo O script contém comandos como jobs , dirs , pushd e popd . Portanto, minha estratégia é source do script no shell quando eu executo o script. Mas muitas vezes me esqueço de source e fico confuso por um tempo, dependendo de quanto tempo eu percebo. Sim, eu mesmo escrevi o roteiro.

Então, há alguma prática recomendada para pessoas esquecidas como eu? Por exemplo, qualquer uma das seguintes opções é uma boa ideia?

  1. Como podemos executar o script sem digitar source , por exemplo, modificando o próprio script de alguma forma?
  2. Como podemos fazer o próprio script me lembrar de source dele? Por exemplo,

    • renomeia o arquivo de script com um prefixo Source_Me ?
    • Ou existe algum comando usado dentro do script para detectar se o script é invocado por source e, se não, a mensagem de erro de saída?
  3. Ou devo me esforçar mais para lembrar quais scripts precisam de source ?

    Obrigado.

por Tim 06.05.2018 / 14:58

5 respostas

4

Se você comprá-lo, ele não requer o bit de execução.

Apenas não torne o script executável. Se você tentar executá-lo (sem obtê-lo), ele simplesmente não será executado ( Permission denied ), portanto, nenhum efeito acontecerá. Se estiver no ambiente PATH, um shell com conclusão (bash ...) nem tentará completá-lo automaticamente com tabulação.

Agora, você pode adicionar apenas .profile , .bashrc ou similar a um alias:

alias myscript='. /path/to/myscript'

Portanto, a partir de agora, ao digitar myscript , ele será gerado e executado conforme pretendido. O shell até completará automaticamente o alias.

    
por 06.05.2018 / 17:10
2

Existem algumas estratégias que você pode usar para imprimir uma mensagem de erro se você executar um script que deve ser originado.

  • Você pode verificar se $0 corresponde ao nome do seu script. se isso acontecer, não será originado, portanto, imprima uma mensagem de erro com uma saída:

    if [ "${0##*/}" = "myscript" ]; then
        echo "Don't run me, source me" >&2
        exit 1
    fi
    

    (Você precisaria ter cuidado para atualizá-lo sempre que seu script for renomeado ...)

    Uma variante disto poderia ser verificar $0 em relação ao conteúdo de /etc/shells , se essa é uma limitação aceitável ( ie seus scripts de shells só são executados usando shells listados lá, que é por não significa uma obrigação).

  • Se o seu script for destinado apenas para uso em um shell interativo, você poderá verificar isso. Se ele for executado em vez de ser originado, ele não estará em um shell interativo:

    case "$-" in
    *i*) ;;
    *) echo "Don't run me, source me" >&2; exit 1 ;;
    esac
    
por 06.05.2018 / 16:58
1

parece que você quer um ponto (.) como

#!/bin/sh
. includeMe.sh

mas se você quiser apenas executar todos os scripts do comando como sem qualquer imperativo "include" ...

  1. é impossível, porque quando você digita um comando ele executa por system () call (tal sintaxe)
  2. isso seria ruim, porque se no script você rodar dessa forma, há o comando exit , ele salvará sua sessão atual do shell

apenas tente criar um script

script.sh:

#!/bin/bash
echo 'bye world';
exit

e execute-o como ./script.sh e compare com . ./script.sh

    
por 06.05.2018 / 14:59
1

Tem que ser um script de origem? Faça uma função. Então, ao invés de

$ . something some args            # run it

ter

$ cat define_something.sh
something() {
    commands here...
}
$ . define_something.sh            # load the function definition
$ something some args              # run the function

Ou, se você quiser que os comandos reais estejam em um script de origem, tenha uma função para obtê-lo:

something() {
    . something "$@"
}

e, em seguida, basta executar something foo bar em vez de . something foo bar .

É claro que as funções ocultam os parâmetros posicionais do ambiente principal do shell, portanto, isso não funcionará lá. Talvez um alias de something a . something , se necessário. (O que já foi sugerido por A.B em sua resposta .)

    
por 06.05.2018 / 18:19
1

How can we make the script itself remind me of source it?

Crie um intérprete personalizado source_reminder e torne-o executável:

#!/bin/sh
printf "%s\n" "Source me!" >&2
exit 1

Depois é só usá-lo no seu script executável:

#!/path/to/your/source_reminder
foo
bar
whatever

Agora, se você executar o script sem o fornecimento, o lembrete fará o seu trabalho.

    
por 06.05.2018 / 22:18