Defina um alias no shell Bourne

1

Estou usando um scrtipt com a instrução 'SH -c command', onde o comando é um alias do bash, esse alias não pode ser interpretado no shell Bourne. ¿Você tem alguma idéia para definir este alias no shell Bourne e fazer com que ele funcione no novo shell? Obrigado a todos!

    
por Salvatore.isc 11.08.2016 / 17:31

2 respostas

2

Eu ficaria surpreso se for um verdadeiro Bourne shell no Linux. Embora o shell Bourne tenha sido portado para o Linux, ele geralmente não é instalado nem empacotado por padrão.

Você só o instalaria para fins de arqueologia.

Talvez você esteja confundindo sh (que hoje em dia se refere a um intérprete ou outro da linguagem POSIX sh ) com o shell Bourne (um shell antigo que também costumava ser chamado de sh (e do qual sh s descende, mas também difere)).

O shell Bourne não possui aliases. Modern sh do.

Os aliases, no entanto, são locais para o shell atual. Se você executar um novo shell (seja bash , sh , csh , zsh ...), esse novo shell não herdará esses aliases.

Você precisaria redefinir esses aliases no novo shell.

bash tem uma maneira de despejar a definição de um de seus alias em uma sintaxe compatível com a de sh . Então você poderia fazer:

alias foo='echo foo' # alias defined in bash
foo_definition=$(alias foo)
sh -c "$foo_definition
foo"

Ou simplesmente:

sh -c "$(alias foo)
foo"

Agora, há um problema que não funciona em todas as implementações de sh . Primeiro você notou que não fizemos:

sh -c "$(alias foo);foo"

O que teria funcionado em não sh implementação.

Isso porque os aliases são realmente como alguma forma de expansão de macro. Como a expansão de alias é feita antes da análise, em alias foo='echo foo'; foo , no momento em que o comando alias é executado, a linha já foi analisada.

Colocar a definição de alias em uma linha e seu uso nas próximas obras para alguns shells, mas alguns outros (como yash ou zsh ) analisam todo o código sh -c como um todo, portanto expansão de alias não vai funcionar lá.

No entanto, como os aliases são mais ou menos macros, ou seja, a substituição de algum texto por outro texto, é melhor fazer a substituição manualmente.

Você pode obter o valor de um alias fazendo:

eval "$(alias foo | sed '1s/ /_/')"

Que armazenaria a definição do foo alias na variável $alias_foo .

Então, você pode fazer:

sh -c "$alias_foo"

Para que o valor do foo alias seja passado como código shell para sh .

Você pode preferir usar funções de aliases para essa finalidade. Como para aliases, as funções são locais para o shell atual. Alguns shells como rc ou bash podem exportar funções para outras invocações do mesmo interpretador.

foo() { echo foo; }
export -f foo
sh -c foo

Funcionaria somente em sistemas em que sh fosse implementado com bash (principalmente apenas Apple OS / X e alguns sistemas baseados em Linux).

Uma abordagem mais portável seria para os aliases despejarem a definição da função no código passado para sh -c :

sh -c "$(typeset -f foo); foo"

Desta vez, nenhum problema com o tempo de expansão, o tempo de análise como funções, em oposição a aliases como funções, são estruturas reais da linguagem.

No entanto, você precisa garantir que a definição da função contenha código com a sintaxe sh válida e não use nenhuma extensão bash .

    
por 11.08.2016 / 17:52
1

Falando sobre Bash em particular -

Isso acontece porque, quando o Bash recebe um comando usando -c , ele é iniciado no modo não interativo e, em particular, a expansão de alias é desativada.

Em geral, você não deve usar aliases em scripts, mas deve usar funções do shell ou outros scripts. Se você realmente quiser usar aliases, tente bash -ic <alias_command> . O -i iniciará o shell no modo interativo, leia seus arquivos de configuração, como /.bashrc , e a expansão de alias será ativada.

Nota - Aliases que o Bash vê virão dos arquivos de configuração, não do shell pai.

    
por 11.08.2016 / 17:55