Làm thế nào để có được đường dẫn đầy đủ của một tệp trong bash?


21

Tôi muốn một cách dễ dàng để có được đường dẫn đầy đủ đến một tập tin. Tôi hiện đang gõ này:

echo `pwd`/file.ext

Cố gắng rút ngắn nó, tôi đã tạo ra một bí danh bash:

alias fp='echo `pwd`/'

Nhưng bây giờ nếu tôi gõ fp file.ext, có một khoảng trắng xuất hiện giữa /file.ext.

Liệu một lệnh như vậy đã tồn tại, và tôi đang thiếu nó? Nếu không, làm thế nào tôi có thể tạo ra một bí danh hoặc hàm như vậy trong bash?

Câu trả lời:


29

Trên các hệ thống linux, bạn nên readlinkcài đặt từ dự án GNU coreutils và có thể làm điều này:

readlink -f file.ext

Các hệ thống Debian / ubfox có thể được cài đặt tiện ích realpath "cung cấp hầu hết các chức năng tương tự như /bin/readlink -ftrong gói coreutils."


readlink -f(hoặc realpath, là một tiện ích cũ hơn được giữ để tương thích) cũng sẽ mở rộng tất cả các liên kết tượng trưng, ​​điều không nhất thiết phải mong muốn.
Gilles 'SO- ngừng trở thành ác quỷ'

8
fyi: không hoạt động trên macosx.
akira

Trên máy Mac của tôi, tôi đã cài đặt coreutils bằng homebrew và nó bao gồm realpath.
Doug Harris

7

Thay vì pwdlệnh, hãy sử dụng PWDbiến (cũng có trong POSIX):

fp () {
  case "$1" in
    /*) printf '%s\n' "$1";;
    *) printf '%s\n' "$PWD/$1";;
  esac
}

Nếu bạn cần hỗ trợ Windows, việc nhận ra các đường dẫn tuyệt đối sẽ phức tạp hơn vì mỗi cổng của các công cụ unix có các quy tắc riêng để dịch các đường dẫn tệp. Với Cygwin, sử dụng cygpathtiện ích.


Có thể đó là sự lựa chọn của bạn nhưng chức năng này sẽ không tạo ra dòng mới.
cYrus

Cách tiếp cận này có lợi thế là chỉ sử dụng các trình dựng vỏ, nhanh hơn so với gọi các nhị phân bên ngoài. bạn nên làm cho sự thật này rõ ràng hơn một chút.
akira

4

để trả lời câu hỏi của bạn với những gì bạn sử dụng ngay bây giờ:

bí danh mở rộng tại vị trí bạn đang gõ ngay bây giờ. bạn đã gõ:

% fp<SPACE>file.ext

điều này trở thành

% echo `pwd`<SPACE>file.exe

bạn có thể sử dụng một chức năng để tránh điều đó:

function fp() {
    echo `pwd`/"$1"
}

bạn có thể sử dụng nó như bình thường:

% fp file.ext

Bạn cần báo giá kép xung quanh các thay thế lệnh và thay thế:echo "`pwd`/$1"
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles: trong hoàn cảnh nào?
akira

2
@akira: Luôn luôn sử dụng dấu ngoặc kép trừ khi bạn muốn kết quả của việc mở rộng được coi là một mẫu hình cầu và kết quả của việc tạo khối được chia thành các từ. Ở đây bạn đang xây dựng một tên tệp duy nhất, vì vậy cần có dấu ngoặc kép (thử chức năng của bạn với một tệp được gọi *trong thư mục chứa các tệp khác).
Gilles 'SO- ngừng trở thành ác quỷ'

' ' được bao bọc bởi shell (zsh trong trường hợp của tôi) và được mở rộng trước khi chúng nhấn chức năng. fp *mang lại /tmp/4cc3ea0c1b34bvì đó là thông số đầu tiên cho hàm. các tham số khác sẽ là các tệp khác trong thư mục. ngay sau khi tôi có một tệp có tên ' ', chức năng vẫn hoạt động như mong đợi, gọi nó bằng "*" hoặc * hoặc *
akira

Bash là "xấu" ở đây vì dường như, bash mang lại những gì bạn đang đề cập đến.
akira

3

Bạn có thể dùng:

realpath file.ext

Tôi không có cái đó. cái đó từ đâu tới?
frabjous

@frabjous: nó dành riêng cho Debian và các công cụ phái sinh và sẽ chỉ được cài đặt nếu bạn đã yêu cầu hoặc gói phụ thuộc vào nó.
Gilles 'SO- ngừng trở thành ác quỷ'

Tôi đang sử dụng Arch. Đó không phải là dựa trên Debian, nhưng dù sao cũng có một gói cho nó trong AUR. Không chắc chắn rằng nó đáng để cài đặt nếu tôi đã có readlink mặc dù.
frabjous

Vâng, đó là một lựa chọn; hoặc bạn có thể xem xét một chức năng, xem Gilles câu trả lời của . Dù sao, điều đó phụ thuộc vào công dụng thực tế mà bạn muốn làm với điều đó (tôi tò mò).
cYrus

@frabjous: Bạn không chỉ định hệ thống nào bạn đang sử dụng, nhưng nếu hệ thống đó sử dụng trình quản lý gói dựa trên Aptitude (Debian, Ubuntu, Mint, v.v.), bạn có thể nhập apt-cache search realpathđể tiết lộ rằng coreutils và đồng bằng ol' realpath gói cả hai đều chứa nó Sau đó, bạn có thể nhập sudo apt-get install realpath(hoặc coreutils) để cài đặt nó.
Michael Scheper

1

Từ /programming//a/3915420/5795941

Đây là cách duy nhất được tôi chấp nhận. Không mở rộng các liên kết như realpath và readlink và là cách làm cổ điển mà tôi đã thấy trên tất cả.

#! /bin/sh
echo "$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")"
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.