นามแฝงและฟังก์ชั่น


17

จากคู่มือทุบตี

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

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

คุณสามารถอธิบายสิ่งที่พวกเขาหมายถึงตามลำดับ?


คำถามที่ดี! ฉันเอนกายสิ่งใหม่วันนี้ ฉันเรียนรู้ 2 สิ่งที่จริงแล้ว: 1) ข้อมูลนี้เกี่ยวกับการขยายนามแฝงในเวลาที่ฟังก์ชั่น def อ่านแล้วและ 2) ว่าฉันควรอ่านคู่มือทุบตีอย่างระมัดระวัง (ซึ่งฉันคิดว่าฉันทำไปแล้ว แต่ดูเหมือนจะไม่ ^^ )
Olivier Dulac

4
คำถามหลักคือทุกคนควรใช้นามแฝงในโหมดไม่โต้ตอบหรือไม่ นั่นคือสิ่งที่มีไว้สำหรับฟังก์ชั่นและนามแฝงทำให้การเขียนสคริปต์ง่ายขึ้นมากขึ้น ฉันไม่เคยต้องการข้อมูลข้างต้นเพราะฉันเจอนามแฝงใน.bashrcไฟล์ที่อยู่ด้านบนสุดเท่านั้น
orion

คำตอบ:


29
  1. นามแฝงจะถูกขยายเมื่อมีการอ่านคำจำกัดความของฟังก์ชันไม่ใช่เมื่อเรียกใช้ฟังก์ชัน ...

    $ echo "สุนัขจิ้งจอกสีน้ำตาลรีบกระโดดข้ามสุนัขขี้เกียจ" > myfile
     
    $ alias myalias = cat
     
    $ myfunc () {
    > myalias myfile
    >}
     
    $ myfunc
    สุนัขจิ้งจอกสีน้ำตาลอย่างรวดเร็วกระโดดข้ามสุนัขขี้เกียจ
     
    $ alias myalias = "ls -l"
     
    $ myalias myfile
    -rw-r - r-- 1 myusername mygroup 45 Dec 13 07:07 myfile
     
    $ myfunc
    สุนัขจิ้งจอกสีน้ำตาลอย่างรวดเร็วกระโดดข้ามสุนัขขี้เกียจ

    แม้ว่าจะmyfuncได้รับการกำหนดให้การโทรmyaliasและฉันได้นิยามใหม่myalias, ยังคงดำเนินความหมายเดิมของmyfunc myaliasเนื่องจากนามแฝงถูกขยายเมื่อฟังก์ชันถูกกำหนด ในความเป็นจริงเปลือกไม่ได้จำได้ว่าmyfuncโทรmyalias; มันเท่านั้นที่รู้ว่าmyfuncสายcat:

    $ พิมพ์ myfunc
    myfunc เป็นฟังก์ชั่น
    myfunc ()
    {
    cat myfile
    }
  2. …นามแฝงที่กำหนดในฟังก์ชั่นจะไม่สามารถใช้งานได้จนกว่าจะมีการใช้งานฟังก์ชันดังกล่าว

    $ echo "สุนัขจิ้งจอกสีน้ำตาลรีบกระโดดข้ามสุนัขขี้เกียจ" > myfile
     
    $ myfunc () {
    > alias myalias = cat
    >}
     
    $ myalias myfile
    -bash: myalias: ไม่พบคำสั่ง
     
    $ myfunc
     
    $ myalias myfile
    สุนัขจิ้งจอกสีน้ำตาลอย่างรวดเร็วกระโดดข้ามสุนัขขี้เกียจ

    myaliasนามแฝงไม่สามารถใช้ได้จนกว่าจะมีmyfuncฟังก์ชั่นได้รับการดำเนินการ (ฉันเชื่อว่ามันจะค่อนข้างแปลกถ้าการกำหนดฟังก์ชั่นที่กำหนด alias นั้นเพียงพอที่จะทำให้ alias ถูกกำหนดไว้)


4
+1 คำตอบที่ดี "ข้อพิสูจน์ที่สำคัญ" ของสิ่งนี้คือถ้าหากใครตั้งใจจะกำหนดฟังก์ชั่นและนามแฝงในสคริปต์ให้วางนิยามนามแฝงไว้ข้างหน้านิยามฟังก์ชั่น! (ชัดเจนตอนนี้ได้รับคำตอบ แต่ฉันไม่รู้สิ่งนี้)
Olivier Dulac

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

มันเหมือนกับความแตกต่างระหว่างการสร้างรถยนต์กับการขับรถ หรือซื้อแซนวิชและกินแซนวิช ผมได้ให้คำตอบที่รายละเอียดเพิ่มเติมเพื่อคำถามอื่น ๆ ของคุณ
G-Man กล่าวว่า 'Reinstate Monica'

ขอบคุณ หลังจากอ่านคำพูดจากคู่มือทุบตีและคำตอบของคุณฉันสับสนเกี่ยวกับความหมายของการเรียกใช้ฟังก์ชัน มันหมายถึงการดำเนินการตามคำนิยามของฟังก์ชั่นหรือเรียกฟังก์ชั่น ดูunix.stackexchange.com/q/384209/674
ทิม

1

.bashrcผมต้องการคำตอบที่ถูกระบุไว้ในประโยคแรกเมื่อฉันพยายามที่ด้านล่างในตัวอย่างข้อมูลของฉัน

alias ls='\ls -F --color=auto --show-control-chars'
alias ll='ls -ahl'
function lf_macro() {
    local CMD=${1:-ls} DIR=${2:-.};
    $CMD $(find $DIR -maxdepth 1 -type f);
}
function lf() { lf_macro ll "$1"; }
function lsf() { lf_macro ls "$1"; }     # list all file, no directories

หลังจากที่unalias -a; source ~/.bashrcฉันพยายามที่จะดำเนินการlfและlsf,

$ lf
-bash: ll: command not found

$ lsf
./file1 ./file2 ./script.sh ...     # no color, no control-chars

$ ls $(find -maxdepth 1 -type f)
./file1 ./file2 ./script.sh* ...

ดูเหมือนว่านามแฝงจะถูกขยายที่นิยามฟังก์ชันไม่ใช่การเรียกใช้ฟังก์ชันเนื่องจาก :

  • เมื่อฉันดำเนินlfการข้อผิดพลาด-bash: ll: command not foundและ
  • เมื่อผมดำเนินการlsf, /usr/bin/lsมีการใช้ไม่ได้รูปแบบนามแฝงไม่มีไฮไลท์สีและตัวอักษรไม่มีการควบคุมหลังจากที่แฟ้มที่ปฏิบัติการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.