Bash: Użyj aliasu w zmiennej

9

Piszę skrypt bash, który uruchamia każdy z argumentów jako polecenie. Działa to dla poleceń w moim PATH, ale nie dla aliasów. Mogę bezpośrednio wywołać alias w skrypcie, ale nie mogę wywołać aliasu, który został przekazany jako argument.

Problem (zakładam) polega na tym, że aliasy są rozwijane przed zmiennymi. Czy istnieje sposób uruchamiania aliasów ze zmiennej?

Przykładowy skrypt:

#!/bin/bash
# File: runall

shopt -s expand_aliases
source ~/.aliases

while (( "$#" )); do
    $1
    shift
done

runall "echo test"działa, ale runall "myalias"dajerunall: line 8: myalias: command not found

Jayson
źródło

Odpowiedzi:

9

Po kilku testach doszedłem do następujących wniosków:

  • Aliasy działają tylko w trybie interaktywnym (dodaj -ido shebang).
  • Aliasy nie są oceniane, gdy pochodzą z interpretowanego źródła (w tym przypadku zmiennej.
  • Możesz uzyskać bash, aby użyć aliasu eval $1. Zauważ, że evalingerowanie w cokolwiek utworzonego za pomocą zmiennej jest niebezpieczne, ale ponieważ cały punkt skryptu wymaga dowolnego wykonania, nie zrobię z tego zbyt wielkiego problemu.

Ze strony podręcznika użytkownika bash:

Aliasy nie są rozwijane, gdy powłoka nie jest interaktywna, chyba że ustawiono opcję powłoki expand_aliases za pomocą shopt (patrz opis shopt w POLECENIA WBUDOWANE POWŁOKI poniżej).

Więc możesz dodać shopt -s expand_aliaseszamiast -i.

Również,

Aliasy są rozszerzane po odczytaniu polecenia, a nie podczas jego wykonywania.

Ponieważ zmienne nie są rozwijane przed odczytaniem polecenia, nie będą dalej rozwijane przy użyciu aliasu.

Kevin
źródło
1
Dobrze wiedzieć. Z ciekawości: dlaczego jest niebezpieczny dla evalzmiennych?
1
@hesse Zastanów się eval "echo $1". Powiedz, że dzwonię ./script.sh "hello;rm -rf ~. Co zostaje stracone? echo hello, a następnie rm -rf ~. Oczywiście jest to wymyślony przykład, ale zasada obowiązuje.
Kevin
dodając evalprzed $1pracą, ponieważ już miałem shopt -s expand_aliases. Dzięki!
Jayson,
1

Miałem podobny problem i udało mi się rozwiązać problem, zmieniając aliasy w funkcje opisane w tej witrynie , która działała dla mnie.

na przykład

alias lsd="ls -lash"

do

function lsd() { ls -lash; }
Aydow
źródło