lệnh realpath không tìm thấy


24

Tôi có debian bóp amd64. Vỏ hiện tại của tôi là bash. Nếu tôi viết như sau trong thiết bị đầu cuối của mình, nó hoạt động:

$ 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

Tệp test.sh của tôi trông như thế này:

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

Nếu tôi cố thực hiện như sau, tôi gặp lỗi

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

Làm cách nào tôi có thể sử dụng lệnh realpath trong tệp bash?

thông tin thêm

$ 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"                                                                                                                                                                          
}           

Câu trả lời:


9

Realpath là một lệnh thực tế hay một kịch bản? Tôi sẽ kiểm tra xem nó đến từ đâu.

$ type -a realpath

Tôi không quen thuộc với công cụ này và do đó, nó có thể không phải là một phần của phân phối bình thường của bạn, có lẽ nó được cài đặt ở một vị trí không chuẩn không có trên Bash $PATHnhưng nằm trong môi trường đăng nhập của bạn $PATH.

Trong mọi trường hợp, typelệnh trên sẽ cho bạn biết lệnh đến từ đâu, tại thời điểm đó bạn có thể thay đổi phương thức bạn gọi nó trong tập lệnh của mình như sau:

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

Hoặc sửa đổi tập lệnh của bạn $PATHđể nó cũng bao gồm vị trí không chuẩn này.

Chức năng trong vỏ

Phần lớn môi trường của bạn không được gọi khi bạn gọi tập lệnh shell. Nếu bạn nghĩ về điều này, điều này rất có ý nghĩa, vì bạn thường không muốn các tập lệnh có tất cả hành lý bổ sung mà môi trường của người dùng có thể có.

Bạn có thể xác định tệp nguồn nào đang cung cấp chức năng này và nguồn đó hoặc chỉ cần hướng dẫn Bash kết hợp môi trường đăng nhập của bạn.

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

Đây là một chức năng, xem chỉnh sửa
Francis

@Francis - yeah các chức năng không được bao gồm khi bạn gọi tập lệnh của mình. Bạn sẽ cần nguồn chúng nếu bạn muốn chúng đi cùng. Tìm ra tập tin nào đang cung cấp chức năng và nguồn nó. Nếu bạn chỉ muốn toàn bộ env của bạn. sau đó sửa đổi cuộc gọi của bạn thành bash #!/bin/bash -l.
slm

Làm thế nào tôi có thể tìm thấy chức năng này đến từ đâu?
Phanxicô

1
@mikeerv - cảm ơn, khi tôi viết bài này tôi vẫn đang sử dụng Fedora 14 không bao gồm realpath. Hệ thống Fedora 19 của tôi hiện bao gồm công cụ này. Cũng lưu ý rằng OP đang sử dụng hạt nhân Debian w / 2.6, do đó, hệ thống của anh ta cũng sẽ bị thiếu realpathkhi có tuổi.
slm

1
@mikeerv - vâng tôi rất ngạc nhiên, đây là một Q cũ, nhưng thông tin về commandnó vẫn hữu ích với tôi. Đó là một cách di động hơn để làm những gì tôi đã thể hiện trên các vỏ POSIX.
slm

27

Có ít nhất hai chương trình được gọi là realpath:

  • Một chương trình cũ từ trước khi GNU coreutils không bao gồm readlink -f. Bây giờ nó không được ủng hộ readlink -f, vì vậy nhiều bản phân phối đã ngừng mang nó.
  • Các realpathchương trình giới thiệu trong GNU coreutils 8.15. Điều này là quá cũ để trong Debian ép hoặc thậm chí khò khè; tại thời điểm viết bài, Debian không ổn định cũng không gửi nó . Chương trình này rất gần với readlink -f.

Vì một số lý do, bạn có một hàm shell mô phỏng hành vi của realpath. Giả lập này là một phần: nếu bạn gọi nó trên một liên kết tượng trưng, ​​nó không theo liên kết tượng trưng.

Vì đây là một hàm shell, có lẽ được tải từ hoặc thông qua .bashrc, nên nó chỉ có sẵn để mã chạy trong vỏ tương tác của bạn. Nếu bạn muốn nó có sẵn cho các chương trình khác, giả sử bạn đang chạy Linux, hãy tạo một tập lệnh mô phỏng realpath:

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

(Điều này không mô phỏng realpathcác tùy chọn dòng lệnh hiếm khi được sử dụng.)


2
Tôi không thể tìm thấy bất kỳ bằng chứng nào trong coreutils git repo rằng realpathchương trình được coi là không được chấp nhận bởi coreutils, hoặc nó không được xây dựng theo mặc định. Vì vậy, Debian phải loại bỏ nó.
Kaz

@Kaz Oh, tốt, chỉ để làm phức tạp vấn đề, coreutils gần đây (8.15) đã giới thiệu một realpathnhị phân, gần nhưng không hoàn toàn giống hệt readlink -f. Ổn định Debian mang 8.13. Debian không ổn định đã chọn giữ chương trình cũ .
Gilles 'SO- ngừng trở nên xấu xa'

Không phải gần đây - đó là tháng 1 năm 2012. savannah.gnu.org/forum/forum.php?forum_id=7076
mikeerv

1
@mikeerv Quá gần đây để phân phối trong câu hỏi (Debian bóp). Thậm chí quá gần đây cho ổn định Debian hiện tại.
Gilles 'SO- ngừng trở nên xấu xa'

Điều đó thật đáng sợ. Làm thế nào cũ của họ là openssl?
mikeerv

8

Nó chỉ hoạt động trong shell, vì tệp script có phạm vi khác nhau và không có quyền truy cập vào các hàm và bí danh cục bộ được xác định trong tệp RC của bạn . Và realpathlệnh thực sự không tồn tại trong hệ thống của bạn.

Vì vậy, hoặc cài đặt realpathtừ gói, xác định chức năng của riêng bạn (như một phần của tập lệnh, kiểm tra một số ví dụ ) hoặc nguồn tệp RC trong tập lệnh của bạn nơi được xác định (ví dụ . ~/.bashrc).


Dưới đây là các bước để cài đặt realpathnếu nó không có mặt:

  • Ubuntu: sudo apt-get install coreutils
  • HĐH X: brew install coreutils

Ubuntu và Debian

Trên Debian hoặc Ubuntu, có vẻ như realpathnên được cài đặt theo mặc định. Tôi đã kiểm tra Debian 8 (Jessie) gần đây và có vẻ như nó đã coreutilsđược cài đặt theo mặc định.

Đã thử nghiệm bằng hình ảnh VM mới:

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

Sau đó, trong VM:

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

Thay vì realpath, bạn cũng có thể sử dụng readlink -f file(hoặc greadlink) được cung cấp theo coreutilsgói.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.