สร้าง Bash alias ที่รับพารามิเตอร์หรือไม่


1270

ฉันเคยใช้ CShell () ซึ่งช่วยให้คุณสร้างนามแฝงที่ใช้พารามิเตอร์ สัญกรณ์เป็นสิ่งที่ชอบ

alias junk="mv \\!* ~/.Trash"

ใน Bash สิ่งนี้ดูเหมือนจะไม่ทำงาน เนื่องจาก Bash มีคุณสมบัติที่มีประโยชน์มากมายฉันจะสมมติว่ามีการใช้งานคุณลักษณะนี้แล้ว แต่ฉันสงสัยว่าอย่างไร



2
ตรวจสอบให้แน่ใจว่าคุณใช้เครื่องหมายคำพูดรอบ ๆ วัตถุ"$1"
Christophe Roussy

คำถามนี้อยู่นอกหัวข้อสำหรับ SO มันได้รับการตอบใน UNIX.SEและคำตอบคือการที่คุณไม่จำเป็นต้องแม้จะรำคาญ "ตัวอย่างเช่นถ้าคุณกำลังจะนามแฝงlsไปls -laแล้วพิมพ์ls foo barจะจริงๆรันls -la foo bar. ในบรรทัดคำสั่ง"
Dan Dascalescu

7
ที่จะไม่ช่วย interpolating ตัวแปรกลางสตริง
Franz Sittampalam

1
นี่คือนามแฝงการทดสอบ lil ที่ฉันใช้เพื่อค้นหาการเข้าใจผิดนี้ ... alias test_args="echo PREFIX --$1-- SUFFIX"ซึ่งเมื่อถูกเรียกด้วยtest_args ABCDผลตอบแทนคอนโซลต่อไปนี้PREFIX ---- SUFFIX ABCD
jxramos

คำตอบ:


2122

Bash alias ไม่ยอมรับพารามิเตอร์โดยตรง คุณจะต้องสร้างฟังก์ชั่น

aliasไม่ยอมรับพารามิเตอร์ แต่สามารถเรียกใช้ฟังก์ชันได้เหมือนกับ alias ตัวอย่างเช่น:

myfunction() {
    #do things with parameters like $1 such as
    mv "$1" "$1.bak"
    cp "$2" "$1"
}


myfunction old.conf new.conf #calls `myfunction`

โดยวิธีการฟังก์ชั่น Bash ที่กำหนดไว้ใน.bashrcไฟล์ของคุณและอื่น ๆ ที่มีอยู่เป็นคำสั่งภายในเปลือกของคุณ ตัวอย่างเช่นคุณสามารถเรียกใช้ฟังก์ชันก่อนหน้านี้เช่นนี้

$ myfunction original.conf my.conf

48
ฉันควรห่อ$1ด้วยเครื่องหมายคำพูด?
Jürgen Paul

263
คุณไม่จำเป็นต้องประกาศนามแฝงด้วยซ้ำ เพียงกำหนดฟังก์ชั่นจะทำ
dinigo

206
หากคุณกำลังเปลี่ยนนามแฝงเป็นฟังก์ชันsourceไอเอ็นจี. bashrc ของคุณจะเพิ่มฟังก์ชัน แต่มันจะไม่ยกเลิกชื่อแทนเก่า เนื่องจากชื่อแทนเป็นแบบอย่างสูงกว่าฟังก์ชั่นจึงจะพยายามใช้นามแฝง unalias <name>คุณต้องทั้งปิดและเปิดเปลือกของคุณหรือสายอื่น บางทีฉันอาจจะช่วยใครซักคนใน 5 นาทีที่ฉันเพิ่งเสียไป
Marty Neal

55
@MartinNeal: เคล็ดลับการประหยัดครั้งเดียวที่ฉันได้เรียนรู้ที่ Sun คือการทำexec bash: มันจะเริ่มเชลล์ใหม่ให้คุณอ่านการตั้งค่าของคุณได้อย่างสะอาดราวกับว่าคุณปิดและเปิดใหม่ แต่ยังคงการตั้งค่าตัวแปรสภาพแวดล้อมของเซสชันนั้นด้วย . นอกจากนี้การดำเนินการbashโดยไม่มี exec จะมีประโยชน์เมื่อคุณต้องการจัดการกับความคิดเหมือนกองซ้อน
Macneil Shonle

21
@mich - ใช่ใส่ตัวแปร bash ในเครื่องหมายคำพูดเสมอ mv "$1" "$1.bak"เช่น ไม่ทราบราคาถ้า $ 1 เป็น "Hello World" คุณจะดำเนินการแทนmv hello world hello world.bak mv "hello world" "hello world.bak"
orion elenzil

208

การปรับคำตอบข้างต้นคุณจะได้รับไวยากรณ์ 1 บรรทัดเช่นเดียวกับนามแฝงซึ่งสะดวกกว่าสำหรับนิยาม ad-hoc ในเชลล์หรือไฟล์. bashrc:

bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }

bash$ myfunction original.conf my.conf

อย่าลืมเซมิโคลอนก่อนปิดวงเล็บปิด ในทำนองเดียวกันสำหรับคำถามจริง:

csh% alias junk="mv \\!* ~/.Trash"

bash$ junk() { mv "$@" ~/.Trash/; }

หรือ:

bash$ junk() { for item in "$@" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }

3
ฉันชอบคำตอบนี้เพราะมันแสดงให้เห็นถึงการวนซ้ำของอาร์กิวเมนต์ที่อาจเข้ามา $ 1 และ $ 2 เป็นเพียงกรณีพิเศษซึ่งแสดงในคำตอบนี้ด้วย
philo vivero

16
เปลี่ยนmv "$1" "$1.bak"; cp "$2" "$1" เป็นmv "$1" "$1.bak" && cp "$2" "$1"ข้อมูลของคุณไม่สูญหายเมื่อพบmvปัญหา (เช่นระบบไฟล์เต็ม)
Henk Langeveld

3
"อย่าลืมเซมิโคลอนก่อนปิดวงเล็บปิด" หลายต่อหลายครั้งนี้! ขอบคุณ :)
Kaushal Modi

และช่องว่างหลังจากวงเล็บแรกและก่อนวงเล็บสุดท้ายจะต้องเช่นกัน
Bryan Chapel

1
@HenkLangeveld ในขณะที่คำพูดของคุณถูกต้องสมบูรณ์มันแสดงให้เห็นว่าคุณได้รับในขณะที่ - ฉันไม่รู้ว่าเมื่อฉันพบข้อผิดพลาด "ไม่มีพื้นที่เหลือบนอุปกรณ์" ครั้งสุดท้าย ;-) (ฉันใช้มันเป็นประจำแม้ว่าเมื่อฉันไม่พบที่ว่างบนเคาน์เตอร์ครัวอีกต่อไป!) ดูเหมือนจะไม่เกิดขึ้นบ่อยครั้งในวันนี้
Peter - Reinstate Monica

124

คำถามถูกถามผิด ๆ คุณไม่ได้สร้างนามแฝงที่ใช้พารามิเตอร์เนื่องจากaliasเพิ่งเพิ่มชื่อที่สองสำหรับบางสิ่งที่มีอยู่แล้ว ฟังก์ชั่นที่ OP ต้องการคือfunctionคำสั่งเพื่อสร้างฟังก์ชั่นใหม่ คุณไม่จำเป็นต้องใช้ชื่อแทนฟังก์ชันเนื่องจากฟังก์ชันมีชื่ออยู่แล้ว

ฉันคิดว่าคุณต้องการสิ่งนี้:

function trash() { mv "$@" ~/.Trash; }

แค่นั้นแหละ! คุณสามารถใช้พารามิเตอร์ $ 1, $ 2, $ 3, etc หรือเพียงแค่ใส่ทุกอย่างด้วย $ @


7
คำตอบนี้บอกว่ามันทั้งหมด ถ้าฉันอ่านจากด้านล่างของหน้านี้ฉันจะได้ประหยัดเวลา
joe

-1 นามแฝงและฟังก์ชันไม่เทียบเท่า ...echo -e '#!/bin/bash\nshopt -s expand_aliases\nalias asrc='\''echo "${BASH_SOURCE[0]}"'\'' # note the '\''s\nfunction fsrc(){ echo "${BASH_SOURCE[0]}";}'>>file2&&echo -e '#!/bin/bash\n. file2\nalias rl='\''readlink -f'\''\nrl $(asrc)\nrl $(fsrc)'>>file1&&chmod +x file1&&./file1;rm -f file1 file2
Fuzzy Logic

คุณควรพูด$@เพื่อสนับสนุนชื่อไฟล์ที่มีช่องว่าง ฯลฯ
ทอมเฮล

มันควรจะเป็นคำอธิบายทั่วไปที่คุณไม่มีพารามิเตอร์นามแฝงคุณใช้ฟังก์ชันแทน ฟังก์ชั่นที่กำหนดเป็นเพียงตัวอย่างในการตอบโต้ตัวอย่างดั้งเดิม ฉันไม่คิดว่าบุคคลนั้นกำลังมองหาฟังก์ชั่นถังขยะทั่วไป อย่างไรก็ตามเพื่อประโยชน์ในการนำเสนอโค้ดที่ดีกว่าฉันได้อัปเดตคำตอบแล้ว
Evan Langlois

1
@FuzzyLogic - ฉันใช้เวลาสองสามนาทีเพื่อลองแกะรหัสในความคิดเห็นของคุณ นั่นเป็นความพยายามที่น่าสนใจในการบรรจุรหัสลงในความคิดเห็นซึ่งคุณไม่สามารถจัดรูปแบบได้อย่างเหมาะสม ฉันยังไม่เข้าใจว่ามันทำอะไรหรือที่สำคัญกว่านั้นคือทำไมมันถึงสนับสนุนการยืนยันของคุณ (ถูกต้อง)
โจ

110

TL; DR: ทำสิ่งนี้แทน

มันง่ายกว่ามากและอ่านได้ง่ายกว่าในการใช้ฟังก์ชั่นมากกว่านามแฝงเพื่อใส่อาร์กิวเมนต์ในคำสั่งกลาง

$ wrap_args() { echo "before $@ after"; }
$ wrap_args 1 2 3
before 1 2 3 after

หากคุณอ่านคุณจะได้เรียนรู้สิ่งต่าง ๆ ที่คุณไม่จำเป็นต้องรู้เกี่ยวกับการประมวลผลอาร์กิวเมนต์ของเชลล์ ความรู้เป็นสิ่งที่อันตราย เพิ่งได้ผลลัพธ์ที่คุณต้องการก่อนที่ด้านมืดจะควบคุมโชคชะตาของคุณตลอดไป

การอธิบาย

bashนามแฝงทำยอมรับข้อโต้แย้ง แต่ที่สิ้นสุด :

$ alias speak=echo
$ speak hello world
hello world

การใส่อาร์กิวเมนต์เข้าไปในคำสั่งกลางผ่านaliasเป็นไปได้จริง แต่มันก็น่าเกลียด

อย่าลองทำที่บ้านนะ!

หากคุณชอบหลีกเลี่ยงข้อ จำกัด และทำในสิ่งที่คนอื่นพูดว่าเป็นไปไม่ได้นี่คือสูตร อย่าโทษฉันเลยถ้าผมของคุณร่วงหล่นและใบหน้าของคุณก็เต็มไปด้วยเขม่านักวิทยาศาสตร์

วิธีแก้ปัญหาคือส่งผ่านอาร์กิวเมนต์ที่aliasยอมรับเฉพาะตอนท้ายไปยัง wrapper ที่จะแทรกไว้ตรงกลางแล้วดำเนินการคำสั่งของคุณ

โซลูชันที่ 1

หากคุณต่อต้านการใช้ฟังก์ชั่นต่อ se คุณสามารถใช้:

$ alias wrap_args='f(){ echo before "$@" after;  unset -f f; }; f'
$ wrap_args x y z
before x y z after

คุณสามารถแทนที่$@ด้วย$1ถ้าคุณต้องการอาร์กิวเมนต์แรกเท่านั้น

คำอธิบาย 1

สิ่งนี้จะสร้างฟังก์ชั่นชั่วคราวfซึ่งส่งผ่านการขัดแย้ง (หมายเหตุที่fเรียกว่าที่สุด) การunset -fลบคำจำกัดความของฟังก์ชั่นในขณะที่นามแฝงจะถูกดำเนินการจึงไม่ได้แขวนรอบหลังจากนั้น

โซลูชันที่ 2

คุณยังสามารถใช้เชลล์ย่อย:

$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'

คำอธิบาย 2

นามแฝงสร้างคำสั่งเช่น:

sh -c 'echo before "$@" after' _

ความคิดเห็นที่:

  • ต้องการตัวยึดตำแหน่ง_แต่อาจเป็นอะไรก็ได้ มันได้รับการตั้งค่าshเป็น$0และจำเป็นต้องมีเพื่อให้ข้อโต้แย้งแรกของผู้ใช้ที่กำหนดไม่ได้รับการบริโภค สาธิต:

    sh -c 'echo Consumed: "$0" Printing: "$@"' alcohol drunken babble
    Consumed: alcohol Printing: drunken babble
  • จำเป็นต้องใช้เครื่องหมายคำพูดเดี่ยวภายในเครื่องหมายคำพูดเดี่ยว นี่คือตัวอย่างของมันที่ไม่ทำงานกับเครื่องหมายคำพูดคู่:

    $ sh -c "echo Consumed: $0 Printing: $@" alcohol drunken babble
    Consumed: -bash Printing:

    นี่คือค่าของเปลือกโต้ตอบของ$0และ$@จะถูกแทนที่เข้ามาในคู่ที่ยกมาก่อนที่shมันจะถูกส่งผ่านไปยัง นี่คือหลักฐาน:

    echo "Consumed: $0 Printing: $@"
    Consumed: -bash Printing:

    sh -cราคาเดียวให้มั่นใจว่าตัวแปรเหล่านี้จะไม่ตีความโดยเปลือกโต้ตอบและจะถูกส่งผ่านไปยังตัวอักษร

    คุณสามารถใช้เครื่องหมายคำพูดคู่และ\$@แต่วิธีปฏิบัติที่ดีที่สุดคือการอ้างถึงข้อโต้แย้งของคุณ (เนื่องจากอาจมีช่องว่าง) และ\"\$@\"ดูน่าเกลียดยิ่งขึ้น แต่อาจช่วยให้คุณชนะการประกวดที่ทำให้งงงวยได้


2
สำหรับโซลูชันที่ 1 ตรวจสอบให้แน่ใจว่าคุณใช้เครื่องหมายคำพูดเดี่ยวและหลีกเลี่ยง \ "ประมาณ $ @ เทคนิคที่มีประโยชน์มากถ้าคุณต้องการมัน ty.
sgtz

โซลูชันที่ 1 ทำงานได้สำหรับฉันห่อ rdesktop-vrdp พร้อมอาร์กิวเมนต์สำหรับแต่ละเซิร์ฟเวอร์ที่ฉันต้องการ
Hsehdar

การยอมรับข้อโต้แย้งในตอนท้ายนั้นเป็นสิ่งที่ฉันต้องการเพื่อแทนที่ "git checkout {branchname}" ด้วย "gc {branchname}" ที่เรียบง่าย ใน. bash_profile ฉันต้องเพิ่มalias gc='git checkout'
AbstractVoid

@sgtz ทำไมคุณต้องการที่จะลบคำพูดรอบ$@? พวกเขาจำเป็นถ้าคุณมีเช่นไฟล์ที่มีช่องว่างในพวกเขา
Tom Hale

@ TomHale นี่เป็นภาษาศาสตร์ แต่ทางออกที่ 1 ไม่มีประโยชน์ถ้าใครบางคนใช้ฟังก์ชั่น (ไม่ว่าด้วยเหตุผลใด) เนื่องจากคุณโดยตรงหลังจากยอมรับตัวเองว่าคุณเปลี่ยนนิยามของฟังก์ชั่นเป็นเวลาดำเนินการของ นามแฝง ประการที่สอง "นามแฝงทุบตีจะยอมรับการขัดแย้ง แต่ในตอนท้าย" มีความหมายมากขึ้น: นามแฝงเป็นคำต่อแทนคำนิยามโดยสตริง พวกเขาไม่จำเป็นต้องยอมรับข้อโต้แย้งคำสั่งที่ดำเนินการผ่านการทดแทน แต่ทำได้ นามแฝงคือการแทนที่ตัวอักษรไม่มีอะไรมากไม่มีอะไรน้อย ไม่ได้หรือไม่
BUFU

39

อีกทางเลือกหนึ่งคือการใช้markerซึ่งเป็นเครื่องมือที่ฉันสร้างขึ้นเมื่อเร็ว ๆ นี้ที่ให้คุณสามารถ "คั่นหน้า" เทมเพลตคำสั่งและวางเคอร์เซอร์ไว้ที่ตัวยึดตำแหน่งคำสั่ง

เครื่องหมายบรรทัดคำสั่ง

ฉันพบว่าส่วนใหญ่ฉันใช้ฟังก์ชันเชลล์ดังนั้นฉันจึงไม่ต้องเขียนคำสั่งที่ใช้บ่อยครั้งแล้วครั้งเล่าในบรรทัดคำสั่ง ปัญหาของการใช้ฟังก์ชั่นสำหรับกรณีการใช้งานนี้กำลังเพิ่มคำศัพท์ใหม่ลงในคำศัพท์คำสั่งของฉันและต้องจำพารามิเตอร์ฟังก์ชันที่อ้างถึงในคำสั่งจริง เป้าหมายของเครื่องหมายคือการกำจัดภาระทางจิตนั้น


14

สิ่งที่คุณต้องทำคือทำฟังก์ชั่นภายในนามแฝง:

$ alias mkcd='_mkcd(){ mkdir "$1"; cd "$1";}; _mkcd'

คุณต้องใส่เครื่องหมายคำพูดคู่ล้อมรอบ "$ 1" เพราะคำพูดเดี่ยวจะไม่ทำงาน


5
นั่นเป็นเรื่องที่ฉลาด แต่นอกเหนือจากข้อเท็จจริงที่ว่าคำถามระบุให้นามแฝงแล้วมีเหตุผลอะไรที่ไม่เพียง แต่ทำให้ฟังก์ชั่นที่มีชื่อเดียวกับนามแฝงในตอนแรก?
xaxxon

1
@xaxxon ไม่จริง แต่มันเป็นวิธีที่ง่ายที่สุดที่ฉันรู้ว่าใช้นามแฝงไม่ใช่ฟังก์ชั่น
Ken Tran

1
สิ่งนี้ใช้ไม่ได้ บน Ubuntu 18 bash: syntax error near unexpected token '{mkdir'ฉันได้รับข้อผิดพลาด
Shital Shah

ไม่มีส่วนท้าย;ภายในฟังก์ชัน_mkcdส่วนใหญ่อาจเกิดจากข้อผิดพลาด
Jetchisel

เว้นช่องว่างก่อนและหลัง{และ}
hesham_EE

10

ต่อไปนี้เป็นสามตัวอย่างของฟังก์ชั่นที่ฉันมีในของฉัน~/.bashrcที่มีหลักนามแฝงที่รับพารามิเตอร์:

#Utility required by all below functions.
#/programming/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
}

อ้างอิง:


ฮะ? นั่นเป็นหน้าที่ไม่ใช่นามแฝง และหนึ่งในการอ้างอิงของคุณคือคำถามนี้
tripleee

2
ไม่มันทำงานเหมือนกับฟังก์ชั่น เช่นเดียวกับคำตอบหลายข้อในที่นี้คุณไม่สามารถสร้างนามแฝงที่ใช้พารามิเตอร์ได้ สิ่งที่คุณสามารถทำได้คือเขียนฟังก์ชั่นซึ่งเป็นสิ่งที่คุณทำ
tripleee

1
@tripleee จากมุมมองของมือใหม่ที่ทุบตีก่อนที่จะอ่านความคิดเห็นของคุณฉันคิดว่ามันเป็นนามแฝง มันทำงานเหมือนอย่างที่ฉันบอกได้ เป็นหลักนามแฝงที่ยอมรับพารามิเตอร์แม้ว่าฉันจะปิดคำศัพท์ ฉันไม่เห็นปัญหา ฉันได้อธิบายลิงก์ไปยังคำตอบอื่น ๆ ในปัญหานี้แล้ว มันช่วยฉันสร้างสิ่งนี้
aliteralmind

1
บางทีนี่อาจไม่ตอบคำถามของ "นามแฝงทุบตีที่ยอมรับพารามิเตอร์" โดยเฉพาะเพราะฉันเข้าใจแล้วว่ามันเป็นไปไม่ได้ แต่ก็ตอบได้อย่างมีประสิทธิภาพ ฉันหายไปนี่อะไร
aliteralmind

2
ตัวอย่างที่ดีจริง ๆ ที่นี่และแสดงความคิดเห็นรหัสอย่าง ความช่วยเหลือที่ดีเยี่ยมสำหรับผู้ที่มาที่หน้านี้
chim

9

Bash alias ยอมรับพารามิเตอร์อย่างแน่นอน ฉันเพิ่งเพิ่มนามแฝงเพื่อสร้างแอปปฏิกิริยาใหม่ซึ่งยอมรับชื่อแอปเป็นพารามิเตอร์ นี่คือกระบวนการของฉัน:

เปิด bash_profile เพื่อแก้ไขในนาโน

nano /.bash_profile

เพิ่มชื่อแทนของคุณหนึ่งรายการต่อบรรทัด:

alias gita='git add .'
alias gitc='git commit -m "$@"'
alias gitpom='git push origin master'
alias creact='npx create-react-app "$@"'

หมายเหตุ: "$ @" ยอมรับพารามิเตอร์ที่ส่งผ่านเช่น "creact my-new-app"

บันทึกและออกจากโปรแกรมแก้ไขนาโน

ctrl + o เพื่อเขียน (กด Enter); ctrl + x เพื่อออก

บอกเทอร์มินัลเพื่อใช้นามแฝงใหม่ใน. bash_profile

source /.bash_profile

แค่นั้นแหละ! ตอนนี้คุณสามารถใช้นามแฝงใหม่ของคุณได้แล้ว


6

หมายเหตุ: ในกรณีที่ความคิดไม่ชัดเจนมันเป็นความคิดที่ดีที่จะใช้นามแฝงสำหรับสิ่งใด ๆ นอกจากนามแฝงคนแรกเป็น 'ฟังก์ชั่นในนามแฝง' และคนที่สองเป็น 'ยากที่จะอ่านเปลี่ยนเส้นทาง / แหล่งที่มา' นอกจากนี้ยังมีข้อบกพร่อง (ซึ่งฉันคิดว่าจะชัดเจน แต่ในกรณีที่คุณสับสน: ฉันไม่ได้หมายความว่าพวกเขาจะใช้จริง ... ทุกที่!)

.................................................. .................................................. ............................................

ฉันเคยตอบแบบนี้มาก่อนและมันก็เป็นแบบนี้มาตลอด:

alias foo='__foo() { unset -f $0; echo "arg1 for foo=$1"; }; __foo()'

ซึ่งดีและดีเว้นแต่คุณจะหลีกเลี่ยงการใช้ฟังก์ชั่นทั้งหมดพร้อมกัน ในกรณีนี้คุณสามารถใช้ประโยชน์จากความสามารถมากมายของ bash ในการเปลี่ยนเส้นทางข้อความ:

alias bar='cat <<< '\''echo arg1 for bar=$1'\'' | source /dev/stdin'

พวกเขาทั้งสองมีความยาวเท่ากันให้หรือใช้อักขระไม่กี่

จริงได้เปรียบคือความแตกต่างเวลาด้านบนเป็น 'วิธีการทำงานและด้านล่างเป็น 'เปลี่ยนเส้นทางแหล่งที่มา' วิธีการ เพื่อพิสูจน์ทฤษฎีนี้เวลาพูดสำหรับตัวเอง:

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

นี่คือส่วนล่างสุดของผลลัพธ์ประมาณ 200 รายการโดยสุ่มช่วงเวลา ดูเหมือนว่าการสร้าง / ทำลายฟังก์ชันใช้เวลามากกว่าการเปลี่ยนเส้นทาง หวังว่านี่จะช่วยผู้เข้าชมในอนาคตสำหรับคำถามนี้ (ไม่ต้องการเก็บไว้กับตัวเอง)


2
มีนามแฝงที่กำหนดฟังก์ชั่นแล้วเรียกใช้ฟังก์ชั่นที่เป็นเพียงโง่ เพียงแค่เขียนฟังก์ชั่น เกือบทุกจุดประสงค์นามแฝงถูกแทนที่ด้วยฟังก์ชันเชลล์
geirha

ในกรณีที่คุณไม่ได้อ่านสิ่งทั้งหมดซึ่งคุณอาจลองฉันแสดงให้เห็นว่าทำไมการใช้ฟังก์ชั่นการใช้งานก็ไม่ดีเท่าที่ควรและยังไม่ได้โง่เลย หยุดการโพสต์และ downvoting เพียงเพราะคุณไม่ชอบมัน ... หรืออย่างน้อยก็ให้คำอธิบายที่ถูกต้อง การเรียกชื่อเป็นสัญญาณแรกที่ใกล้เคียงกับความคิด ...
osirisgothra

1
คนที่สอง (นามแฝงบาร์) มีผลข้างเคียงหลายประการ ประการแรกคำสั่งไม่สามารถใช้ stdin ประการที่สองหากไม่มีข้อโต้แย้งใด ๆ หลังจาก alias ข้อโต้แย้งใด ๆ ก็ตามที่เชลล์เกิดขึ้นจะได้รับการส่งแทน การใช้ฟังก์ชั่นหลีกเลี่ยงผลข้างเคียงเหล่านี้ทั้งหมด (การใช้แมวไร้ประโยชน์เช่นกัน)
geirha

2
เฮ้ฉันไม่เคยบอกว่ามันเป็นความคิดที่ดีที่จะทำสิ่งนี้ฉันแค่บอกว่ายังมีวิธีอื่นที่จะไปเกี่ยวกับเรื่องนี้ - แนวคิดหลักที่นี่คือคุณไม่ควรใช้ฟังก์ชั่นในนามแฝงเพราะมันช้ากว่าซับซ้อน เปลี่ยนเส้นทางฉันคิดว่ามันจะชัดเจน แต่ฉันเดาว่าฉันต้องสะกดมันออกมาให้ทุกคน (ซึ่งฉันก็ถูกตะโกนด้วยเพราะการโพสต์นั้น
ค่อนข้าง

1
เนื่องจากการกำหนดเวลาของแถบเป็น 0 ทั้งหมดฉันจึงสงสัยว่าเชลล์ไม่ได้จับเวลาอย่างถูกต้อง ขอให้สังเกตว่าข้อความเวลาจะถูกพิมพ์ก่อนที่คำสั่งจะทำงานหรือไม่ ถ้าอย่างนั้นมันก็ไม่มีอะไรเลยแล้วทำการแสดงแถบดังนั้นคุณจึงไม่ต้องวัดแท่งเลย ทำสิ่งที่ซับซ้อนมากขึ้นหรือวนซ้ำขนาดใหญ่ในแถบเพื่อให้คุณสามารถทำให้ชัดเจนมากขึ้นว่าคุณไม่มี
Evan Langlois

6

หากคุณกำลังมองหาวิธีทั่วไปในการใช้พารามิเตอร์ทั้งหมดกับฟังก์ชั่นไม่ใช่แค่จำนวนหนึ่งหรือสองหรือจำนวนฮาร์ดโค้ดอื่น ๆ คุณสามารถทำได้ด้วยวิธีนี้:

#!/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;

ดังนั้นในตัวอย่างข้างต้นฉันส่งพารามิเตอร์ทั้งหมดจากเมื่อฉันเรียกใช้runjarไปยังนามแฝง

ตัวอย่างเช่นถ้าฉันไม่ว่ามันจะสิ้นสุดการทำงานจริงrunjar hi there java -jar myjar.jar hi thereถ้าฉันไม่ว่ามันจะทำงานrunjar one two threejava -jar myjar.jar one two three

ฉันชอบ$@วิธีแก้ปัญหาแบบนี้เพราะมันใช้ได้กับ params ไม่กี่ตัว


4
ทำไมไม่เพียงแค่ตั้งชื่อฟังก์ชั่นrunjarแทนที่จะทำให้มันเป็นนามแฝงของฟังก์ชั่น? ดูเหมือนซับซ้อนโดยไม่จำเป็น!
Evan Langlois

ฟังก์ชั่น @EvanLanglois เป็นalias-ed อัตโนมัติ(หรือมีคุณสมบัติของสิ่งต่าง ๆ ที่ส่งไปยังalias) ในไฟล์ทุบตี? ถ้าใช่มันเป็นเพียงแค่ฉันไม่ได้รู้ว่า
มิคาห์

ไม่เข้าใจสิ่งที่คุณหมายถึง นามแฝงเป็นชื่ออื่นไม่ว่าจะเป็นบุคคลหรือฟังก์ชัน ดังนั้นคุณสร้างฟังก์ชั่นจากนั้นคุณสร้างชื่อที่สองสำหรับฟังก์ชั่น ไม่มีอะไรพิเศษเกี่ยวกับนามแฝงเป็นเพียงชื่อที่สองและไม่จำเป็นต้องใช้ สิ่งที่คุณพิมพ์ที่บรรทัดคำสั่งอาจเป็นฟังก์ชันภายในหรือภายนอกดังนั้น "ฟังก์ชัน" จึงสร้างคำสั่งใหม่ไม่ใช่นามแฝง
Evan Langlois

4
นี่ไร้จุดหมาย alias runjar='java -jar myjar.jar'มันเป็นเช่นเดียวกับ นามแฝงยอมรับการขัดแย้ง แต่ท้ายที่สุดเท่านั้น
Tom Hale

6

ด้วยความเคารพทุกคนที่บอกว่าคุณไม่สามารถแทรกพารามิเตอร์ตรงกลางของนามแฝงที่ฉันเพิ่งทดสอบและพบว่ามันใช้งานได้

นามแฝง mycommand = "python3" $ 1 "script.py --folderoutput RESULTS /"

เมื่อฉันวิ่งคำสั่งของฉัน foobar มันทำงานเหมือนกับว่าฉันได้พิมพ์คำสั่งออกมานาน


แน่นอนว่านามแฝงสามารถรับพารามิเตอร์ฉันมีอายุใช้สิ่งนี้เช่น: นามแฝงกระทำ = "git กระทำ -m $ 1"
agapitocandemor

ไม่ได้ผลสำหรับฉัน: alias myalias="echo 1 "$1" 3"; myalias 2ให้ฉัน:1 3 2
dirdi

4

มีเหตุผลทางเทคนิคที่ถูกต้องตามกฎหมายที่จะต้องการวิธีการแก้ปัญหาทั่วไปของปัญหานามแฝงทุบตีที่ไม่ได้มีกลไกในการใช้การโต้แย้งตำแหน่งโดยพลการ เหตุผลหนึ่งคือหากคำสั่งที่คุณต้องการดำเนินการจะได้รับผลกระทบในทางลบจากการเปลี่ยนแปลงสภาพแวดล้อมที่เป็นผลมาจากการเรียกใช้ฟังก์ชัน ในกรณีอื่น ๆควรใช้ฟังก์ชั่น

สิ่งที่บังคับให้ฉันพยายามแก้ไขเมื่อเร็ว ๆ นี้คือฉันต้องการสร้างคำสั่งแบบย่อสำหรับการพิมพ์คำจำกัดความของตัวแปรและฟังก์ชั่น ดังนั้นฉันจึงเขียนฟังก์ชันบางอย่างเพื่อจุดประสงค์นั้น อย่างไรก็ตามมีตัวแปรบางอย่างที่เปลี่ยนแปลง (หรืออาจจะ) โดยการเรียกฟังก์ชันเอง ในหมู่พวกเขาคือ:

FUNCNAME BASH_SOURCE BASH_LINENO BASH_ARGC BASH_ARGV

คำสั่งพื้นฐานที่ฉันใช้ (ในฟังก์ชั่น) เพื่อพิมพ์ตัวแปรแปรปรวน ในเอาต์พุตของฟอร์มโดยคำสั่ง set คือ:

sv () { set | grep --color=never -- "^$1=.*"; }

เช่น:

> V=voodoo
sv V
V=voodoo

ปัญหา: สิ่งนี้จะไม่พิมพ์คำจำกัดความของตัวแปรที่กล่าวถึงข้างต้นเนื่องจากอยู่ใน บริบทปัจจุบันเช่นหากอยู่ในพร้อมต์เชลล์แบบโต้ตอบ (หรือไม่ใช้ในการเรียกใช้ฟังก์ชันใด ๆ ) FUNCNAME จะไม่ถูกกำหนด แต่ฟังก์ชั่นของฉันบอกข้อมูลผิด:

> sv FUNCNAME
FUNCNAME=([0]="sv")

ทางออกหนึ่งที่ฉันคิดขึ้นได้ถูกกล่าวถึงโดยคนอื่นในโพสต์อื่น ๆ ในหัวข้อนี้ สำหรับคำสั่งเฉพาะนี้เพื่อพิมพ์ defns. และซึ่งต้องการเพียงหนึ่งอาร์กิวเมนต์ฉันทำสิ่งนี้:

alias asv='(grep -- "^$(cat -)=.*" <(set)) <<<'

ซึ่งให้เอาต์พุตที่ถูกต้อง (ไม่มี) และสถานะผลลัพธ์ (false):

> asv FUNCNAME
> echo $?
1

อย่างไรก็ตามฉันยังรู้สึกถูกบังคับให้ต้องหาวิธีแก้ปัญหาที่ใช้กับข้อโต้แย้งจำนวนมากโดยพลการ

วิธีแก้ปัญหาทั่วไปในการส่งผ่านอาร์กิวเมนต์โดยพลการไปยังคำสั่ง Bash Aliased:

# (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".

เช่น:

> . 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

สิ่งที่ดีเกี่ยวกับการแก้ปัญหานี้คือเทคนิคพิเศษทั้งหมดที่ใช้ในการจัดการพารามิเตอร์ตำแหน่ง (อาร์กิวเมนต์) กับคำสั่งจะทำงานเมื่อเขียนคำสั่งที่ติดอยู่ ข้อแตกต่างเพียงอย่างเดียวคือต้องใช้ไวยากรณ์ของอาร์เรย์

เช่น,

หากคุณต้องการ "$ @" ให้ใช้ "$ {CMD_ARGV [@]}"

หากคุณต้องการ "$ #" ให้ใช้ "$ {# CMD_ARGV [@]}"

เป็นต้น


3

เมื่อฉันทำโครงการสนุกและฉันยังคงใช้ มันแสดงอนิเมชั่นบางอย่างในขณะที่ฉันคัดลอกไฟล์ผ่านcpcommand coz cpไม่แสดงอะไรเลยและมันก็น่าหงุดหงิด ดังนั้นฉันทำนามแฝงนี้

alias cp="~/SCR/spiner cp"

และนี่คือสคริปต์สปินเนอร์

#!/bin/bash

#Set timer
T=$(date +%s)

#Add some color
. ~/SCR/color

#Animation sprites
sprite=( "(* )  ( *)" " (* )( *) " " ( *)(* ) " "( *)  (* )" "(* )  ( *)" )

#Print empty line and hide cursor
printf "\n${COF}"

#Exit function
function bye { printf "${CON}"; [ -e /proc/$pid ] && kill -9 $pid; exit; }; trap bye INT

#Run our command and get its pid
"$@" & pid=$!

#Waiting animation
i=0; while [ -e /proc/$pid ]; do sleep 0.1

    printf "\r${GRN}Please wait... ${YLW}${sprite[$i]}${DEF}"
    ((i++)); [[ $i = ${#sprite[@]} ]] && i=0

done

#Print time and exit
T=$(($(date +%s)-$T))
printf "\n\nTime taken: $(date -u -d @${T} +'%T')\n"

bye

มันมีลักษณะเช่นนี้

ป้อนคำอธิบายรูปภาพที่นี่

แอนิเมชั่นขี่จักรยาน)

ป้อนคำอธิบายรูปภาพที่นี่


2

สำหรับการรับพารามิเตอร์คุณควรใช้ฟังก์ชั่น!

อย่างไรก็ตาม $ @ รับการตีความเมื่อสร้างนามแฝงแทนในระหว่างการดำเนินการของนามแฝงและการหลีกเลี่ยง $ จะไม่ทำงานเช่นกัน ฉันจะแก้ปัญหานี้ได้อย่างไร

คุณต้องใช้ฟังก์ชั่นเชลล์แทนนามแฝงเพื่อกำจัดปัญหานี้ คุณสามารถกำหนด foo ดังนี้:

function foo() { /path/to/command "$@" ;}

หรือ

foo() { /path/to/command "$@" ;}

สุดท้ายเรียก foo ของคุณ () โดยใช้ไวยากรณ์ต่อไปนี้:

foo arg1 arg2 argN

ตรวจสอบให้แน่ใจว่าคุณเพิ่ม foo () ลงในไฟล์~/.bash_profileหรือ~/.zshrc

ในกรณีของคุณสิ่งนี้จะใช้ได้

function trash() { mv $@ ~/.Trash; }

ฉันไม่เข้าใจความคิดของคุณ ฉันคิดว่ามันไม่สำคัญเมื่อข้อโต้แย้งได้รับการตีความ นามแฝงยอมรับพารามิเตอร์มากที่สุดเท่าที่คุณต้องการในตอนท้าย
Timo

แต่มันจะเป็นการดีกว่าถ้าทำด้วยฟังก์ชั่น นามแฝงไม่ได้มีไว้สำหรับสิ่งนั้น
Ahmad Awais

1

ฟังก์ชั่นนั้นเกือบจะเป็นคำตอบที่ได้รับการสนับสนุนและยืนยันโดยคำพูดนี้จาก man page: "สำหรับเกือบทุกจุดประสงค์นามแฝงจะถูกแทนที่ด้วยฟังก์ชันเชลล์"

เพื่อความสมบูรณ์และเนื่องจากอาจมีประโยชน์ (ซินแทกซ์ที่มีน้ำหนักเบากว่าเล็กน้อย) จึงอาจสังเกตได้ว่าเมื่อพารามิเตอร์ติดตามนามแฝงพวกเขายังคงสามารถใช้งานได้ นี่อาจเป็นวิธีที่ง่ายที่สุดในการสาธิตด้วยตัวอย่าง:

alias ssh_disc='ssh -O stop'

อนุญาตให้ฉันพิมพ์ smth เช่น ssh_disc myhostซึ่งเพิ่มขึ้นตามที่คาดไว้:ssh -O stop myhost

สิ่งนี้มีประโยชน์สำหรับคำสั่งที่รับอาร์กิวเมนต์ที่ซับซ้อน (ความจำของฉันไม่ใช่สิ่งที่มันใช้อีกต่อไป ... )


1

ทั้งฟังก์ชั่นและนามแฝงสามารถใช้พารามิเตอร์ตามที่คนอื่น ๆ ได้แสดงไว้ที่นี่ นอกจากนี้ฉันอยากจะชี้ให้เห็นอีกสองด้าน:

1. ฟังก์ชั่นทำงานในขอบเขตของตัวเองนามแฝงขอบเขตหุ้น

อาจเป็นประโยชน์ในการทราบความแตกต่างนี้ในกรณีที่คุณต้องการซ่อนหรือเปิดเผยบางสิ่งบางอย่าง นอกจากนี้ยังแสดงให้เห็นว่าฟังก์ชั่นเป็นตัวเลือกที่ดีกว่าสำหรับการห่อหุ้ม

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 

เอาท์พุท:

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. wrapper script เป็นตัวเลือกที่ดีกว่า

มันเกิดขึ้นกับฉันหลายครั้งว่าไม่พบนามแฝงหรือฟังก์ชั่นเมื่อเข้าสู่ระบบผ่านsshหรือเกี่ยวข้องกับการเปลี่ยนชื่อผู้ใช้หรือสภาพแวดล้อมที่มีผู้ใช้หลายคน มีเคล็ดลับและกลอุบายในการจัดหาไฟล์ dot หรือสิ่งที่น่าสนใจที่มีนามแฝง: alias sd='sudo 'ให้นามแฝงต่อไปนี้alias install='sd apt-get install'ทำงานตามที่คาดไว้ (สังเกตเห็นพื้นที่พิเศษในsd='sudo ') อย่างไรก็ตามสคริปต์แรปเปอร์ทำงานได้ดีกว่าฟังก์ชั่นหรือชื่อแทนในกรณีเช่นนี้ ข้อได้เปรียบหลักของสคริปต์ตัวห่อหุ้มคือสามารถมองเห็น / เรียกใช้งานได้สำหรับเส้นทางที่ต้องการ (เช่น / usr / loca / bin /) โดยที่ฟังก์ชัน / นามแฝงจำเป็นต้องมีแหล่งที่มาก่อนจึงจะสามารถใช้งานได้ ตัวอย่างเช่นคุณใส่ฟังก์ชันใน ~ / .bash_profile หรือ ~ / .bashrcbashแต่ต่อมาเปลี่ยนเป็นเชลล์อื่น (เช่นzsh) จากนั้นฟังก์ชั่นจะมองไม่เห็นอีกต่อไป ดังนั้นเมื่อคุณมีข้อสงสัยสคริปต์ห่อหุ้มมักจะเป็นโซลูชั่นที่น่าเชื่อถือและพกพาได้เสมอ


1
ทำไมคุณคิดว่ารุ่นฟังก์ชั่นไม่ทำงาน
tripleee

@tripleee ฉันได้แก้ไขโพสต์เพื่อให้อ่านง่ายขึ้น ภายใต้หัวข้อ "1. นามแฝงใช้งานได้ฟังก์ชั่น ... " ฉันแสดงให้เห็นว่าเหตุใดรุ่นของฟังก์ชันจึงไม่ทำงาน และอาจจะตอบคำถามโดยตรงฟังก์ชั่นแนะนำขอบเขตใหม่ที่นามแฝงไม่ได้
biocyberman

คุณบอกว่ามันใช้งานไม่ได้ แต่ฉันไม่เชื่อคุณ sourceในฟังก์ชั่นใช้งานได้ดี
tripleee

1
f () { source /tmp/nst; }ทำสิ่งที่ฉันคาดหวัง บางทีคุณอาจPATHจะผิดดังนั้นมันจึงทำงานผิดปกติactivateหรือบางอย่าง; แต่การทำงานsourceจากฟังก์ชั่นใช้งานได้ดี
tripleee

1
BTW, อีกครั้ง: ใช้functionคำหลักในคำจำกัดความของคุณ, ดูwiki.bash-hackers.org/scripting/obsolete - function funcname {เป็นไวยากรณ์ ksh โบราณที่รองรับการย้อนกลับเข้ากันได้กับเชลล์ POSIX ก่อนหน้าในขณะที่funcname() {เป็นไวยากรณ์มาตรฐาน POSIX อย่างเป็นทางการ function funcname() {เป็นความผิดพลาดของทั้งสองที่ไม่เข้ากันกับ ksh โบราณหรือเข้ากันได้กับ POSIX sh และสิ่งที่หลีกเลี่ยงได้ดีที่สุด
ชาร์ลส์ดัฟฟี่

1

นี่คือตัวอย่าง:

alias gcommit='function _f() { git add -A; git commit -m "$1"; } ; _f'

สำคัญมาก:

  1. มีพื้นที่หลัง{และก่อน}คือ
  2. มี;คำสั่งหลังจากแต่ละคำสั่งในลำดับ หากคุณลืมสิ่งนี้หลังจากคำสั่งสุดท้ายคุณจะเห็น>พรอมต์แทน!
  3. อาร์กิวเมนต์ถูกล้อมรอบด้วยเครื่องหมายคำพูดเป็น "$1"

2
ไม่จำเป็นต้องสร้างชื่อแทนให้กับฟังก์ชันเพียงใช้ฟังก์ชันโดยตรง
user3439894

1

ดังที่ผู้อื่นชี้ให้เห็นแล้วการใช้ฟังก์ชั่นควรได้รับการพิจารณาว่าเป็นแนวปฏิบัติที่ดีที่สุด

อย่างไรก็ตามนี่คือวิธีการอีกวิธีหนึ่งโดยใช้ประโยชน์จากxargs:

alias junk="xargs -I "{}" -- mv "{}" "~/.Trash" <<< "

โปรดทราบว่าสิ่งนี้มีผลข้างเคียงเกี่ยวกับการเปลี่ยนเส้นทางของสตรีม


0

คุณไม่ต้องทำอะไรเลยนามแฝงทำสิ่งนี้โดยอัตโนมัติ

ตัวอย่างเช่นถ้าฉันต้องการสร้างต้นแบบต้นกำเนิดดึง git ดึงพารามิเตอร์ฉันสามารถสร้างชื่อแทนดังนี้

alias gpull = 'git pull origin '

และเมื่อเรียกจริงคุณสามารถส่ง 'master' (ชื่อสาขา) เป็นพารามิเตอร์เช่นนี้

gpull master
//or any other branch
gpull mybranch

สิ่งนี้ไม่ตอบคำถามเนื่องจากข้อโต้แย้งไม่สามารถวางได้อย่างอิสระ แต่ท้ายที่สุดเท่านั้น
dirdi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.