Am folosit pentru a utiliza CShell ([tag:csh]), care vă permite să facă un alias care ia un parametru. Notația a fost ceva de genul
alias junk="mv \\!* ~/.Trash"
În Bash, acest lucru nu pare să funcționeze. Având în vedere că Bash are o multitudine de caracteristici utile, mi-ar presupune că aceasta a fost pusă în aplicare, dar mă întreb cum.
Bash alias nu accepta direct parametrii. Va trebui să creați o funcție.
alias
nu acceptă parametri, dar o funcție poate fi numit ca un alias. De exemplu:
myfunction() {
#do things with parameters like $1 such as
mv "$1" "$1.bak"
cp "$2" "$1"
}
myfunction old.conf new.conf #calls `myfunction`
Apropo, Bash funcțiile definite în ta `.bashrc și alte fișiere sunt disponibile comenzi în coajă. Deci, de exemplu, puteți apela mai devreme funcție de genul asta
$ myfunction original.conf my.conf
Rafinare răspunsul de mai sus, se poate obține 1-linie de sintaxă ca tine poate pentru pseudonime, care este mai convenabil pentru ad-hoc definiții într-o coajă sau .bashrc fișiere:
bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }
bash$ myfunction original.conf my.conf
Don't uita semi-colon înainte de închiderea dreapta-suport. În mod similar, pentru întrebarea reală:
csh% alias junk="mv \\!* ~/.Trash"
bash$ junk() { mv "$@" ~/.Trash/; }
Sau:
bash$ junk() { for item in "$@" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }
Întrebarea este rugat pur și simplu greșit. Nu't face un alias care are parametrii pentru alias
doar adaugă un al doilea nume pentru ceva care deja există. Funcționalitatea OP vrea este "funcție" comandă pentru a crea o nouă funcție. Nu trebuie să alias funcția funcția are deja un nume.
Cred ca vrei ceva de genul asta :
function trash() { mv "$@" ~/.Trash; }
Ca's a! Puteți utiliza parametrii de $1, $2, $3, etc, sau doar lucruri-le pe toate cu $@
De mult mai ușor și mai ușor de citit pentru a utiliza o funcție decât un alias pentru a pune argumente în mijlocul de o comandă.
$ wrap_args() { echo "before $@ after"; }
$ wrap_args 1 2 3
before 1 2 3 after
Dacă ai citit pe, te'll învăța lucruri pe care nu't trebuie să știți despre shell argument de prelucrare. Cunoașterea este periculos. Doar obține rezultatul pe care îl doriți, înainte de partea întunecată pentru totdeauna controlează destinul.
bash
pseudonime nu accepta argumente, dar numai la sfârșitul**:
$ alias speak=echo
$ speak hello world
hello world
Punerea argumente în mijloc de comandă prin alias
este într-adevăr posibil, dar devine urât.
Dacă vă place eluda limitările și de a face ceea ce alții spun că este imposibil, aici's rețeta. Doar don't da vina pe mine daca parul tau devine obosit și fața ta se termină acoperit de funingine nebun om de știință-stil.
Soluție este de a trece la argumentele care alias
acceptă numai la sfârșitul unui înveliș care va introduce-le în mijloc și apoi executa comanda ta.
Daca're într-adevăr împotriva folosind o funcție în sine, puteți folosi:
$ alias wrap_args='f(){ echo before "$@" after; unset -f f; }; f'
$ wrap_args x y z
before x y z after
Puteți înlocui $@
cu $1
dacă doriți doar primul argument.
Explicație 1
Acest lucru creează o temporar funcția "f", care este trecut la argumente (rețineți că " f " este numit la final). Anii unset -f
elimină definiția funcției ca alias-ul este executat ca't atârnă în jurul valorii de după aceea.
Puteți folosi, de asemenea, un subshell:
$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'
Explicație 2
Alias construiește o comandă cum ar fi:
sh -c 'echo before "$@" after' _
Comentarii:
_
este necesar, dar ar putea fi orice. Devine setat la " sh " 's $0
, și este necesar, astfel încât primul a dat de utilizator argumente don't se consumă. Demonstrație:sh -c 'echo Consumate: "$0" Imprimare: "$@"' alcool beat da de gol Consumate: alcool Imprimare: beat da de gol
$ sh -c "echo Consumate: $0 de Imprimare: $@" alcool beat da de gol Consumate: -bash Imprimare:
Aici valorile shell interactiv's $0
și $@
sunt înlocuite în dublu citat înainte e a trecut la "sh". Aici's dovada:
echo "Consumate: $0 de Imprimare: $@" Consumate: -bash Imprimare:
Single-citate de a se asigura că aceste variabile nu sunt interpretate de către shell interactiv, și au trecut literalmente să sh -c
.
Ai putea folosi dublu-citate și \$@
, dar cea mai bună practică este să-ți citez argumente (ca acestea pot conține spații), și `\"\$@\" arata chiar mai urat, dar poate ajuta să câștige o confuzie concurs unde amețit de păr este o condiție prealabilă pentru intrarea.
O soluție alternativă este de a utiliza marker, un instrument de am'am creat recent, care vă permite să "bookmark" comanda template-uri și ușor de a plasa cursorul la comanda deținătorilor de loc:
Am constatat că cele mai multe din timp, am'm, folosind coajă de funcții, astfel încât nu't trebuie să scrie comenzi frecvent utilizate din nou și din nou în linie de comandă. Problema de utilizarea funcțiilor pentru acest caz de utilizare, este adăugarea de noi termeni pentru comanda mea de vocabular și avea să-și amintească ce funcții parametri, consultați în real-comandă. Marker scopul este de a elimina că sarcina mentale.
Aici's sunt trei exemple de funcții I-au în~/.bashrc`, care sunt în esență pseudonime care acceptă un parametru:
#Utility required by all below functions.
#https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-bash-variable#comment21953456_3232433
alias trim="sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'"
.
:<<COMMENT
Alias function for recursive deletion, with are-you-sure prompt.
Example:
srf /home/myusername/django_files/rest_tutorial/rest_venv/
Parameter is required, and must be at least one non-whitespace character.
Short description: Stored in SRF_DESC
With the following setting, this is *not* added to the history:
export HISTIGNORE="*rm -r*:srf *"
- https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash
See:
- y/n prompt: https://stackoverflow.com/a/3232082/2736496
- Alias w/param: https://stackoverflow.com/a/7131683/2736496
COMMENT
#SRF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
SRF_DESC="srf [path]: Recursive deletion, with y/n prompt\n"
srf() {
#Exit if no parameter is provided (if it's the empty string)
param=$(echo "$1" | trim)
echo "$param"
if [ -z "$param" ] #http://tldp.org/LDP/abs/html/comparison-ops.html
then
echo "Required parameter missing. Cancelled"; return
fi
#Actual line-breaks required in order to expand the variable.
#- https://stackoverflow.com/a/4296147/2736496
read -r -p "About to
sudo rm -rf \"$param\"
Are you sure? [y/N] " response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y)$ ]]
then
sudo rm -rf "$param"
else
echo "Cancelled."
fi
}
.
:<<COMMENT
Delete item from history based on its line number. No prompt.
Short description: Stored in HX_DESC
Examples
hx 112
hx 3
See:
- https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HX_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HX_DESC="hx [linenum]: Delete history item at line number\n"
hx() {
history -d "$1"
}
.
:<<COMMENT
Deletes all lines from the history that match a search string, with a
prompt. The history file is then reloaded into memory.
Short description: Stored in HXF_DESC
Examples
hxf "rm -rf"
hxf ^source
Parameter is required, and must be at least one non-whitespace character.
With the following setting, this is *not* added to the history:
export HISTIGNORE="*hxf *"
- https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash
See:
- https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HXF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HXF_DESC="hxf [searchterm]: Delete all history items matching search term, with y/n prompt\n"
hxf() {
#Exit if no parameter is provided (if it's the empty string)
param=$(echo "$1" | trim)
echo "$param"
if [ -z "$param" ] #http://tldp.org/LDP/abs/html/comparison-ops.html
then
echo "Required parameter missing. Cancelled"; return
fi
read -r -p "About to delete all items from history that match \"$param\". Are you sure? [y/N] " response
response=${response,,} # tolower
if [[ $response =~ ^(yes|y)$ ]]
then
#Delete all matched items from the file, and duplicate it to a temp
#location.
grep -v "$param" "$HISTFILE" > /tmp/history
#Clear all items in the current sessions history (in memory). This
#empties out $HISTFILE.
history -c
#Overwrite the actual history file with the temp one.
mv /tmp/history "$HISTFILE"
#Now reload it.
history -r "$HISTFILE" #Alternative: exec bash
else
echo "Cancelled."
fi
}
Referințe:
Tot ce trebuie să faceți este să facă o funcție în interiorul unui alias:
$ alias mkcd='funcția _mkcd(){mkdir "$1"; cd "$1"}; _mkcd'
Ai trebuie pune ghilimele jurul "$1" pentru ghilimele simple, nu va funcționa.
NB: în cazul În care ideea nu e't de evident, este o idee proastă să folosească pseudonime pentru nimic, dar pseudonime, primul fiind 'funcția într-un alias' si cel de-al doilea fiind 'greu de citit redirect/sursa'. De asemenea, există defecte (pe care am gândul ar fi evident, dar doar în cazul în care sunteți confuz: nu mă refer la ele pentru a fi utilizate efectiv... oriunde!)
................................................................................................................................................
Am'am răspuns la acest lucru înainte, și întotdeauna a fost așa în trecut:
alias foo='__foo() { unset -f $0; echo "arg1 for foo=$1"; }; __foo()'
ceea ce este bine și bun, dacă nu se evită utilizarea funcțiilor toate împreună. în cazul în care puteți profita de bash's vasta capacitatea de a redirecționa text:
alias bar='cat <<< '\''echo arg1 for bar=$1'\'' | source /dev/stdin'
Ambele sunt de aproximativ aceeași lungime a da sau de a lua câteva personaje.
La real kicker este diferenta de timp, partea de sus fiind 'funcția metoda' si partea de jos fiind 'redirect-sursă' metoda. Pentru a demonstra această teorie, calendarul vorbește de la sine:
arg1 for foo=FOOVALUE
real 0m0.011s user 0m0.004s sys 0m0.008s # <--time spent in foo
real 0m0.000s user 0m0.000s sys 0m0.000s # <--time spent in bar
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.010s user 0m0.004s sys 0m0.004s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.011s user 0m0.000s sys 0m0.012s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.012s user 0m0.004s sys 0m0.004s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
real 0m0.010s user 0m0.008s sys 0m0.004s
real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
Aceasta este partea de jos de aproximativ 200 de rezultate, face la intervale aleatorii. Se pare că funcția de creare/distrugere ia mai mult timp decât de redirecționare. Sperăm că acest lucru va ajuta pe viitorii vizitatori la această întrebare (n't vreau să-l păstrez pentru mine).
Daca're în căutarea pentru un mod generic de a aplica toate params pentru o funcție, nu doar una sau două, sau unele alte hardcoded sumă, poți face asta în acest fel:
#!/usr/bin/env bash
# you would want to `source` this file, maybe in your .bash_profile?
function runjar_fn(){
java -jar myjar.jar "$@";
}
alias runjar=runjar_fn;
Deci, în exemplul de mai sus, trec toți parametrii de când alerg `runjar la alias.
De exemplu, dacă am făcut runjar bună nu ar fi ajuns de fapt rulează java -jar myjar.jar salut. Dacă am făcut runjar unu, doi, trei
ar rula java -jar myjar.jar unu, doi, trei`.
Imi place acest $ @
pe bază de soluție, deoarece acesta funcționează cu orice număr de params.
Acolo sunt legitime motive tehnice, să vrei un generalizate soluție la problema de bash alias nu are un mecanism pentru a lua o repoziționa arbitrar de argumente. Unul dintre motive este dacă comanda pe care doriți să executa i-ar fi afectate de modificări ale mediului și care rezultă din executarea unei funcții. În toate alte cazuri, funcții ar trebui să fie utilizate.
Ce, recent, m-a constrâns să încerce o soluție pentru acest lucru este că am vrut să creeze un abreviat comenzi pentru imprimarea definiții de variabile și funcții. Așa că am scris niște funcții pentru acest scop. Cu toate acestea, există anumite variabile care sunt (sau pot fi) s-a schimbat printr-un apel de funcție în sine. Printre acestea sunt:
FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV
Pe bază de comandă am fost folosind (într-o funcție) pentru a imprima variabilă defns. în formă de ieșire de comandă set a fost:
sv () { set | grep --color=never -- "^$1=.*"; }
E. g.:
> V=voodoo
sv V
V=voodoo
Problema: Asta nu't de imprimare definițiile variabilelor menționate mai sus, deoarece acestea sunt în contextul actual, de exemplu, dacă într-un shell interactiv prompt (sau nu, în orice apeluri de funcții), FUNCNAME e't definite. Dar funcția mea spune-mi informații greșite:
> sv FUNCNAME
FUNCNAME=([0]="sv")
O solutie am venit cu a fost menționat de către alții în alte posturi pe acest subiect. Specifice pentru această comandă pentru a imprima variabilă defns., și care necesită un singur argument, am făcut acest lucru:
alias asv='(grep -- "^$(cat -)=.*" <(set)) <<<'
Care dă corectă de ieșire (nici unul), și rezultatul de stare (fals):
> asv FUNCNAME
> echo $?
1
Cu toate acestea, m-am simțit obligat să găsească o soluție care funcționează pentru numere arbitrare de argumente.
O Soluție Generală Pentru A Trece Arbitrar De Argumente Pentru O Petrecere Alias Comanda:
# (I put this code in a file "alias-arg.sh"):
# cmd [arg1 ...] – an experimental command that optionally takes args,
# which are printed as "cmd(arg1 ...)"
#
# Also sets global variable "CMD_DONE" to "true".
#
cmd () { echo "cmd($@)"; declare -g CMD_DONE=true; }
# Now set up an alias "ac2" that passes to cmd two arguments placed
# after the alias, but passes them to cmd with their order reversed:
#
# ac2 cmd_arg2 cmd_arg1 – calls "cmd" as: "cmd cmd_arg1 cmd_arg2"
#
alias ac2='
# Set up cmd to be execed after f() finishes:
#
trap '\''cmd "${CMD_ARGV[1]}" "${CMD_ARGV[0]}"'\'' SIGUSR1;
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# (^This is the actually execed command^)
#
# f [arg0 arg1 ...] – acquires args and sets up trap to run cmd:
f () {
declare -ag CMD_ARGV=("$@"); # array to give args to cmd
kill -SIGUSR1 $$; # this causes cmd to be run
trap SIGUSR1; # unset the trap for SIGUSR1
unset CMD_ARGV; # clean up env...
unset f; # incl. this function!
};
f' # Finally, exec f, which will receive the args following "ac2".
E. g.:
> . alias-arg.sh
> ac2 one two
cmd(two one)
>
> # Check to see that command run via trap affects this environment:
> asv CMD_DONE
CMD_DONE=true
Un lucru frumos despre această soluție este că toate trucuri speciale folosite pentru a ocupa poziție parametri (argumente) pentru comenzi va funcționa atunci când compun prins de comandă. Singura diferență este că matrice sintaxă trebuie să fie utilizate.
E. g.,
Dacă vrei "$@", utilizați "${CMD_ARGV[@]}".
Dacă vrei "$#", utilizați "${#CMD_ARGV[@]}".
Etc.
Pentru a lua parametri, ar trebui să utilizați funcții!
Cu toate acestea $@ ia interpretat la crearea alias în loc de timpul executării alias și evadarea $ nu funcționează. Cum pot rezolva aceasta problema?
Aveți nevoie pentru a utiliza shell funcție în loc de un nume fals pentru a scăpa de această problemă. Puteți defini foo după cum urmează:
function foo() { /path/to/command "$@" ;}
SAU
foo() { /path/to/command "$@" ;}
În cele din urmă, sună-ți foo (), folosind următoarea sintaxă:
foo arg1 arg2 argN
Asigurați-vă că adăugați foo() a ~/.bash_profile "sau"~/.zshrc
de fișier.
In cazul tau, acest lucru va funcționa
function trash() { mv $@ ~/.Trash; }
Ambele funcții și pseudonime pot folosi parametri ca și alții au arătat aici. În plus, aș dori să subliniez o serie de alte aspecte:
1. funcția se execută în propriul domeniu de aplicare, alias acțiuni domeniul de aplicare
Acesta poate fi util să se cunoască această diferență în cazurile în care aveți nevoie pentru a ascunde sau expune ceva. De asemenea, sugerează că o funcție este cea mai bună alegere pentru încapsulare.
function tfunc(){
GlobalFromFunc="Global From Func" # Function set global variable by default
local FromFunc="onetwothree from func" # Set a local variable
}
alias talias='local LocalFromAlias="Local from Alias"; GlobalFromAlias="Global From Alias" # Cant hide a variable with local here '
# Test variables set by tfunc
tfunc # call tfunc
echo $GlobalFromFunc # This is visible
echo $LocalFromFunc # This is not visible
# Test variables set by talias
# call talias
talias
echo $GlobalFromAlias # This is invisible
echo $LocalFromAlias # This variable is unset and unusable
Ieșire:
bash-3.2$ # Test variables set by tfunc
bash-3.2$ tfunc # call tfunc
bash-3.2$ echo $GlobalFromFunc # This is visible
Global From Func
bash-3.2$ echo $LocalFromFunc # This is not visible
bash-3.2$ # Test variables set by talias
bash-3.2$ # call talias
bash-3.2$ talias
bash: local: can only be used in a function
bash-3.2$ echo $GlobalFromAlias # This is invisible
Global From Alias
bash-3.2$ echo $LocalFromAlias # This variable is unset and unusable
2. script înveliș este o alegere mai bună
Asta mi s-a întâmplat de mai multe ori că un alias sau funcție nu poate fi găsit atunci când logare prin ssh
sau care implică trecerea de nume de utilizator sau mediu multi-utilizator. Există sfaturi și trucuri de aprovizionare cu dot fișiere, sau acest interesant cu alias: alias sd='sudo '
vă permite acest ulterioare alias alias instala='sd apt-get install' de lucru, după cum ne așteptam (observați spațiu suplimentar în sd='sudo '
). Cu toate acestea, un script înveliș funcționează mai bine decât o funcție sau un alias în astfel de cazuri. Principalul avantaj cu un script înveliș este că acesta este vizibil/executabil pentru sub destinat cale (de exemplu /usr/loca/bin/) în care ca o funcție/alias trebuie să fie obținute înainte este utilizabil. De exemplu, ai pus-o funcție într-o ~/.bash_profile sau ~/.bashrc pentru bash
, dar mai târziu a trece la un alt shell (de exemplu zsh
) atunci funcția nu mai este vizibil.
Deci, atunci când sunteți în îndoială, un script înveliș este întotdeauna cele mai fiabile și soluție portabilă.
Funcțiile sunt într-adevăr aproape întotdeauna răspunsul ca deja amplu contribuit și confirmat prin acest citat din pagina de om: "Pentru aproape orice scop, alias-uri sunt înlocuite de coajă de funcții."
Pentru completitudine și pentru că acest lucru poate fi util (marginal mai ușor de sintaxă) ar putea fi observat că atunci când parametrul(s) urmați alias, ele pot fi folosite în continuare (deși acest lucru nu't adresa OP's cerință). Aceasta este, probabil, cel mai simplu de a demonstra cu un exemplu:
alias ssh_disc='ssh -O stop'
permite-mi să tastați ceva de genul ssh_disc serverulmeu
, care devine extins cum era de așteptat, ca: ssh -O opri serverulmeu
Acest lucru poate fi util pentru comenzi care avea argumente complexe (memoria mea e't ceea ce este utilizarea sa fie mai...)