Vraag Hoe voer ik een alias uit in een shellscript?


Ik heb een uitvoerbaar bestand mpiexec, waarvan het volledige pad is ~/petsc-3.2-p6/petsc-arch/bin/mpiexec. Omdat ik deze opdracht in verschillende mappen wil uitvoeren (zonder het hele pad opnieuw te moeten typen), stel ik een alias in mijn huis in .bashrc het dossier:

alias petsc="~/petsc-3.2-p6/petsc-arch/bin/mpiexec"  

waardoor ik dit kan uitvoeren mpiexec bestand op de opdrachtprompt eenvoudig door te typen:

petsc myexecutable

Ik heb geprobeerd een shell-scriptbestand te maken met de naam script, met mijn nieuwe alias petsc als een commando. Na het geven van mijn shellscript de juiste rechten (met chmod), Probeerde ik het script uit te voeren. Het gaf me echter de volgende foutmelding:

./script: line 1: petsc: command not found

Ik weet dat ik gewoon het volledige pad naar de kan schrijven mpiexec bestand, maar het is lastig om het volledige pad telkens te schrijven wanneer ik een nieuw script wil schrijven. Is er een manier om mijn alias te gebruiken? petsc in het scriptbestand? Is er een manier waarop ik mijn kan bewerken? .bashrc of .bash_profile om dit te laten gebeuren?


76
2018-01-26 18:11


oorsprong


Hoe zit het met het toevoegen van het alias aan .bash_aliases ? Ook hoe over het aliasing van het absolute pad in plaats van relatieve pad wilt alias petsc='/home/user/petsc-3.2-p6/petsc-arch/bin/mpiexec' - Nitin Venkatesh
@nitstorm: geen van beide oplossingen lijkt te werken ... ik krijg nog steeds dezelfde fout als voorheen - Paul


antwoorden:


  1. Gebruik in uw shellscript het volledige pad in plaats van een alias.

  2. Stel in uw shellscript een variabele, verschillende syntaxis in

    petsc='/home/your_user/petsc-3.2-p6/petsc-arch/bin/mpiexec'
    
    $petsc myexecutable
    
  3. Gebruik een functie in uw script. Waarschijnlijk beter als petsc is complex

    function petsc () {
        command 1
        command 2
    }
    
    petsc myexecutable
    
  4. Geef uw aliassen een bron

    shopt -s expand_aliases
    source /home/your_user/.bashrc
    

U wilt waarschijnlijk niet uw bron .bashrcdus, IMO, een van de eerste 3 zou beter zijn.


58
2018-01-26 18:19



Punt 4 werkt niet, tenzij u gebruikt shopt -s expand_aliases in hetzelfde script. - enzotib
Uw suggestie 2) werkt, maar ik wil dezelfde opdracht in meerdere shellscripts kunnen gebruiken zonder de eerste regel petsc = "..." te hoeven schrijven. Is er een manier om dit te doen? - Paul
Het lijkt erop dat u de opdracht op een meer standaardlocatie moet plaatsen, zoals /usr/local/bin - Panther
@enzotib - dank u, ik heb dat toegevoegd aan mijn antwoord. - Panther
In het punt 2 stelt u geen alias in maar een variabele. - pabouk


Aliassen worden afgeschaft ten gunste van shell-functies. Van de bash handmatige pagina:

For almost every purpose, aliases are superseded by shell functions.

Om een ​​functie te maken en deze naar subshells te exporteren, plaatst u het volgende in uw ~/.bashrc:

petsc() {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
}
export -f petsc

Dan kunt u vanuit uw scripts vrijelijk uw opdracht aanroepen.


49
2018-01-26 18:28



Dat werkt bijna ... het enige probleem is dat ik verschillende vlaggen moet kunnen doorgeven aan de uitvoerbare "mpiexec" ... Ik moet bijvoorbeeld iets als "petsc -n 40 myexecutable" kunnen uitvoeren met de alias "petsc" - Paul
@Paul: ik heb toegevoegd "$@" alleen om argumenten af ​​te handelen. - enzotib


Shell-functies en aliassen zijn beperkt tot de shell en werken niet in uitgevoerde shellscripts. Alternatieven voor uw zaak:

  • (als je de moeite niet neemt om te gebruiken mpiexec in plaats van petsc) Toevoegen $HOME/petsc-3.2-p6/petsc-arch/bin aan jouw PATH variabel. Dit kan gedaan worden door te bewerken ~/.profile en toevoegen:

    PATH="$HOME/petsc-3.2-p6/petsc-arch/bin:$PATH"
    

    Log opnieuw in om deze wijzigingen toe te passen

  • Maak de map aan ~/bin en

    • maak een wrapscript genaamd petsc met daarin:

      #!/bin/sh
      exec ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
      
    • als het programma dit toelaat, kun je het shellscript overslaan en een symlink maken met behulp van de opdracht:

      ln -s ~/petsc-3.2-p6/petsc-arch/bin/mpiexec ~/bin/petsc
      

11
2018-01-26 18:52





In bash 4 kunt u speciale variabele gebruiken: $BASH_ALIASES.

Bijvoorbeeld:

$ alias foo="echo test"
$ echo ${BASH_ALIASES[foo]}
echo test
$ echo `${BASH_ALIASES[foo]}` bar
test bar

U kunt ook als variabele definiëren en vervolgens opdrachtsubstitutie of gebruiken eval.

Dus in plaats van bijvoorbeeld de alias te definiëren zoals:

alias foo="echo test"

definieer het als:

foo="echo test"

in plaats daarvan. Voer het vervolgens uit door:

find . -type f -exec sh -c "eval $foo" \;

of:

find . -type f -exec sh -c "echo `$foo`" \;

6
2018-06-01 22:31



Hoewel aliassen worden afgeschaft ten gunste van shell-functies, is dit antwoord de enige die moet worden geaccepteerd. Zelfs de oude Debian 8 heeft versie 4 van bash, dus de ${BASH_ALIASES[alias]} is een leuke optie. Anders moest ik veel regels van mijn .bash_aliases bewerken om andere dingen toe te passen. Dank je. - erm3nda


Je kunt bash forceren om je script uit te voeren als een interactieve shell met de vlag -i. Dit zal je vertellen .bashrc bestand om aliassen en andere functies te definiëren.

Voorbeeld:

~ $ grep ll .bashrc
alias ll='ls -lah'
~ $ cat script.sh 
#!/bin/sh

ll
~ $ bash script.sh 
script.sh: line 3: ll: command not found
~ $ bash -i script.sh
..directory contents..

Meer informatie:

$ man bash

3
2018-01-10 08:03



.bashrc wordt ook gelezen tijdens de niet-interactieve uitvoering van de SSH-opdracht (vandaar dat het bovenaan de controle heeft op interactiviteit) - muru
Ik heb mijn antwoord bewerkt. Bedankt @muru - Amado Martinez


  1. In .bash_aliases:

    petsc { ~ / petsc-3.2-p6 / petsc-arch / bin / mpiexec "$ @" }

Of zet de functie erin .bashrc als je het vaak noemt. Dat wordt verteld in .bashrc alleen configuratie-instellingen van bash is opgeslagen.

  1. In Terminal: source .bash_aliases
  2. petsc arg(s)

Voordeel: u heeft het niet nodig export -f petscin .bash_aliases. Aliassen zijn verouderd, maar ik veronderstel dat ze worden gebruikt .bash_aliases is niet.


3
2018-03-28 09:07



Ik vind deze oplossing leuk, ik zal het later proberen - Greenonline


  1. Gebruik uw aliassen in uw shellscript.
  2. Bron uw script in uw huidige, interactieve shell in plaats van het uit te voeren.

Dus als je een bestand hebt met de naam script.sh met je commando's die aliassen gebruiken, typ je gewoon:

source script.sh

2
2017-07-25 00:00



@DavidFoerster Deze methode werkt prima. Sourcing van een script met de . of source buiiltin veroorzaakt de actueel shell om alle opdrachten erin uit te voeren. Als alias uitbreiding zou plaatsvinden in de shell waarin . of source wordt uitgevoerd, het gebeurt. Het is echter belangrijk om te beseffen dat deze methode slechts soms nuttig is, omdat je vaak een script in zijn eigen shell, met zijn eigen omgeving, moet of wil uitvoeren. Shell-scripts die zijn geschreven met de intentie om op de gebruikelijke manier te worden uitgevoerd, moeten meestal niet afkomstig zijn - ze werken vaak niet goed. - Eliah Kagan
@EliahKagan: bedankt. Nu begrijp ik wat het antwoord zou moeten betekenen. Ik zal een verklaring toevoegen. - David Foerster


(EDIT: verwijderde functies omdat ik het bellen van mpiexec verkeerd gelezen heb.)

Als het enige dat je nodig hebt minder typen is, waarom zet je dan niet gewoon de map in $ PATH? Of maak een symlink naar mpiexec vanuit een map in $ PATH? Of (mijn favoriet) zet de alias in een script dat u in het aanroepende script hebt gevonden?


1
2018-01-26 19:22



De reden waarom ik het niet in mijn $ PATH kan stoppen is omdat ik een ander 'mpiexec' bestand in een andere map heb die alredy is in mijn $ PATH. Als ik het pad toevoeg naar deze nieuwe 'mpiexec', zal het waarschijnlijk beide proberen uit te voeren ... zou het niet? - Paul
Kan niet begrijpen waarom niet gewoon gebruiken "$@". - enzotib
Paul, het zal proberen degene uit te voeren die de eerste is in het PATH, niet allebei. - unhammer
enzotib, ah Ik heb de manier waarop mpiexec werd genoemd verkeerd gelezen, ik dacht dat het alle args als één nodig had. Zal mijn antwoord bewerken :) - unhammer


ALIASES
   ...
   Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS
   below).

Dus het echte antwoord op deze vraag, voor diegenen die daadwerkelijke aliassen in shell-scripts willen gebruiken in plaats van alternatieven voor hen, is:

#!/bin/bash

shopt -s expand_aliases

alias foo=bar

foo whatever

Wat betreft waarom Ik zou dit willen doen: Vanwege ongebruikelijke omstandigheden moet ik een Dockerfile bedriegen door te denken dat het een shellscript is.


1
2017-07-18 00:50