ไม่พบคำสั่ง realpath


24

ฉันมี debian บีบ amd64 เปลือกปัจจุบันของฉันคือทุบตี ถ้าฉันเขียนสิ่งต่อไปนี้ในเครื่องเทอร์มินัลมันใช้งานได้

$ uname -a
Linux core 2.6.32-5-amd64 #1 SMP Fri May 10 08:43:19 UTC 2013 x86_64 GNU/Linux
$ echo $SHELL
/bin/bash                                                                                                                                                                                     
$ echo $(realpath test.sh)                                                                                                                                                     
/home/ffortier/test.sh

ไฟล์ test.sh ของฉันมีลักษณะดังนี้:

#!/bin/bash
echo $(realpath "$1")

หากฉันพยายามที่จะดำเนินการต่อไปนี้ฉันได้รับข้อผิดพลาด

$ ./test.sh test.sh 
./test.sh: line 2: realpath: command not found

ฉันจะใช้คำสั่ง realpath ภายในไฟล์ bash ได้อย่างไร

ข้อมูลเพิ่มเติม

$ type -a realpath
realpath is a function                                                                                                                                                                        
realpath ()                                                                                                                                                                                   
{                                                                                                                                                                                             
    f=$@;                                                                                                                                                                                     
    if [ -d "$f" ]; then                                                                                                                                                                      
        base="";                                                                                                                                                                              
        dir="$f";                                                                                                                                                                             
    else                                                                                                                                                                                      
        base="/$(basename "$f")";                                                                                                                                                             
        dir=$(dirname "$f");                                                                                                                                                                  
    fi;                                                                                                                                                                                       
    dir=$(cd "$dir" && /bin/pwd);                                                                                                                                                             
    echo "$dir$base"                                                                                                                                                                          
}           

คำตอบ:


9

realpath เป็นคำสั่งจริงหรือสคริปต์หรือไม่? ฉันจะตรวจสอบเพื่อดูว่ามันมาจากไหน

$ type -a realpath

ฉันไม่คุ้นเคยกับเครื่องมือนี้และอาจไม่ได้เป็นส่วนหนึ่งของการแจกแจงแบบปกติของคุณบางทีอาจถูกติดตั้งในตำแหน่งที่ไม่ได้มาตรฐานซึ่งไม่ปรากฏใน Bash $PATHแต่อยู่ในสภาพแวดล้อมการเข้าสู่ระบบของ$PATHคุณ

ไม่ว่าในกรณีใดtypeคำสั่งด้านบนจะแสดงให้คุณทราบว่าคำสั่งนั้นมาจากไหน ณ จุดที่คุณสามารถเปลี่ยนวิธีการที่คุณเรียกใช้ในสคริปต์ของคุณดังนี้:

echo $(/path/to/realpath test.sh)

หรือแก้ไขสคริปต์ของคุณ$PATHเพื่อให้มีตำแหน่งที่ไม่ได้มาตรฐานนี้ด้วย

ฟังก์ชั่นในเปลือก

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

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

#!/bin/bash -l
echo $(realpath "$1")

มันเป็นฟังก์ชั่นโปรดดูการแก้ไข
ฟรานซิส

@ ฟรานซิส - ใช่ฟังก์ชั่นจะไม่รวมอยู่เมื่อคุณเรียกใช้สคริปต์ของคุณ คุณจะต้องแหล่งที่มาพวกเขาหากคุณต้องการให้พวกเขามา ค้นหาไฟล์ที่ให้ฟังก์ชันและแหล่งที่มา ถ้าคุณแค่ต้องการ env ทั้งหมด #!/bin/bash -lแล้วแก้ไขการเรียกร้องให้ทุบตี
slm

ฉันจะหาฟังก์ชั่นนี้ได้จากที่ใด
ฟรานซิส

1
@mikeserv - ขอบคุณเมื่อผมเขียนนี้ผมก็ยังคงใช้ Fedora 14 realpathซึ่งไม่ได้รวม ระบบ Fedora 19 ของฉันตอนนี้มีเครื่องมือนี้ นอกจากนี้สังเกตว่า OP กำลังใช้เคอร์เนล Debian ด้วย 2.6 ดังนั้นระบบของเขาก็จะหายไปrealpathตามอายุ
slm

1
@mikeserv - ใช่ฉันรู้สึกประหลาดใจนี่เป็นคำถามเก่า ๆ ตอนนี้ แต่ข้อมูลเกี่ยวกับcommandยังคงมีประโยชน์สำหรับฉัน มันเป็นวิธีที่พกพาได้มากกว่าในการทำสิ่งที่ฉันแสดงในเชลล์ POSIX
slm

27

มีอย่างน้อยสองโปรแกรมที่เรียกว่าrealpath:

  • โปรแกรมเก่าจากหลังเมื่อ GNU coreutils ไม่ได้รวมreadlink -fอยู่ ตอนนี้เลิกใช้แล้วreadlink -fดังนั้นการกระจายจำนวนมากจึงหยุดดำเนินการ
  • realpathโปรแกรมแนะนำใน GNU coreutils 8.15 นี่มันแก่เกินกว่าที่จะบีบ Debian หรือแม้แต่เสียงฮืด ๆ ในขณะที่เขียนDebian ไม่เสถียรก็ไม่ได้จัดส่งเช่นกัน readlink -fโปรแกรมนี้เป็นมากใกล้เคียงกับ

realpathด้วยเหตุผลบางอย่างคุณจะมีฟังก์ชั่นเปลือกซึ่งส่วนหนึ่งจำลองลักษณะการทำงานของ การจำลองนี้เป็นบางส่วน: ถ้าคุณเรียกมันว่าบนลิงก์สัญลักษณ์มันจะไม่ไปตามลิงก์สัญลักษณ์

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

#!/bin/sh
readlink -f -- "$@"

(นี่ไม่ได้จำลองrealpathตัวเลือกบรรทัดคำสั่งที่ไม่ค่อยได้ใช้)


2
ฉันไม่สามารถหาหลักฐานใด ๆ ใน coreutils git repo ว่าrealpathโปรแกรมนั้นถูกพิจารณาว่าเลิกใช้งานโดย coreutils หรือว่ามันไม่ได้ถูกสร้างขึ้นตามค่าเริ่มต้น ดังนั้นเดเบียนจะต้องลบมันออก
Kaz

@Kaz โอ้ดีเพียงเพื่อซับซ้อนเรื่อง coreutils เมื่อเร็ว ๆ นี้ (8.15) แนะนำrealpathไบนารีซึ่งใกล้ แต่ไม่เหมือนกันreadlink -fทั้งหมด เดเบียนเสถียร 8.13 เดเบียนไม่เสถียรเลือกที่จะเก็บโปรแกรมดั้งเดิมไว้
Gilles 'หยุดความชั่วร้าย'

มันไม่ได้ว่าเมื่อเร็ว ๆ นี้ - มันเป็น ม.ค. 2012 savannah.gnu.org/forum/forum.php?forum_id=7076
mikeserv

1
@mikeserv ไกลเกินไปสำหรับการกระจายในคำถาม (Debian บีบ) แม้ล่าสุดสำหรับเดเบียนเสถียรในปัจจุบัน
Gilles 'หยุดความชั่วร้าย'

มันช่างน่ากลัวจริงๆ พวกเขาอายุเท่าopensslไหร่
mikeserv

8

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

ดังนั้นการติดตั้งrealpathจากแพคเกจให้กำหนดฟังก์ชั่นของคุณเอง (เป็นส่วนหนึ่งของสคริปต์ตรวจสอบตัวอย่าง ) หรือแหล่งที่มาของไฟล์rcในสคริปต์ของคุณซึ่งมันถูกกำหนดไว้ (เช่น. ~/.bashrc)


นี่คือขั้นตอนในการติดตั้งrealpathหากไม่มีอยู่:

  • อูบุนตู: sudo apt-get install coreutils
  • OS X: brew install coreutils

อูบุนตูและเดเบียน

บน Debian หรือ Ubuntu ดูเหมือนว่าrealpathควรจะติดตั้งโดยค่าเริ่มต้น ฉันได้ตรวจสอบใน Debian 8 ล่าสุด (เจสซี) และดูเหมือนว่าจะcoreutilsติดตั้งตามค่าเริ่มต้น

ทดสอบโดยใช้อิมเมจ VM ใหม่:

$ vagrant init debian/jessie64 && vagrant up --provider virtualbox && vagrant ssh
$ vagrant init ubuntu/vivid64 && vagrant up --provider virtualbox && vagrant ssh

จากนั้นใน VM:

$ type -a realpath
realpath is /usr/bin/realpath

แทนที่จะใช้realpathคุณสามารถใช้readlink -f file(หรือgreadlink) จัดทำโดยcoreutilsแพคเกจเช่นกัน


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