Kiểm tra xem thư mục có tồn tại khi sử dụng ký tự nhà (~) trong bash không


16

Tại sao bashkiểm tra sau nếu một thư mục thất bại?

if [ ! -d "~/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

~/Desktopthực sự tồn tại Đây là trên máy Mac.


Vấn đề là với loại kịch bản này

read -p "Provide the destination directory: " DESTINATION

if [ ! -d $DESTINATION ]; then
    echo "\t'$DESTINATION' does not exist." >&2;
    exit 1;
fi

1
Giống như khi bạn làm cd "~/Desktop"bạn cũng gặp lỗi. Nó phải được bỏ trích dẫn hoặc được lưu trữ dưới dạng một biến (không có dấu ngoặc kép). Ví dụ: a=~/Desktop; cd $a;hoạt động nhưng không a="~/Desktop"; cd Desktop;Xem serverfault.com/questions/417252/ từ
dylnmc

Câu trả lời:


7

Justin đã làm rõ câu hỏi của mình trong bình luận đầu tiên về câu trả lời của quanta. Anh ta đang đọc trong một dòng văn bản bằng cách sử dụng read(hoặc bằng một số phương tiện động khác) và muốn mở rộng dấu ngã.

Câu hỏi trở thành "Làm thế nào để bạn thực hiện mở rộng dấu ngã trên nội dung của một biến?"

Cách tiếp cận chung là sử dụng eval, nhưng nó đi kèm với một số cảnh báo quan trọng, cụ thể là khoảng trắng và chuyển hướng đầu ra ( >) trong biến. Những điều sau đây có vẻ hiệu quả với tôi:

read -p "Provide the destination directory: " DESTINATION

if [ ! -d "`eval echo ${DESTINATION//>}`" ]; then
    echo "'$DESTINATION' does not exist." >&2;
    exit 1;
fi

Hãy thử nó với từng đầu vào sau:

~
~/existing_dir
~/existing dir with spaces
~/nonexistant_dir
~/nonexistant dir with spaces
~/string containing > redirection
~/string containing > redirection > again and >> again

Giải trình

  • Các ký tự ${mypath//>}loại bỏ các >ký tự có thể ghi đè lên một tệp trong eval.
  • Việc eval echo ...mở rộng dấu ngã thực sự là gì
  • Các trích dẫn kép xung quanh evallà để hỗ trợ tên tệp có khoảng trắng.

Để bổ sung cho điều này, bạn có thể cải thiện UX bằng cách thêm -etùy chọn để đọc:

read -p "Provide the destination directory: " -e DESTINATION

Bây giờ khi người dùng gõ vào dấu ngã và tab, nó sẽ mở rộng. Tuy nhiên, cách tiếp cận này không thay thế cách tiếp cận eval ở trên, vì việc mở rộng chỉ xảy ra nếu người dùng nhấn tab. Nếu anh ta chỉ gõ ~ / foo và nhấn enter, nó sẽ vẫn là dấu ngã.

Xem thêm:


23

Xóa các dấu ngoặc kép xung quanh thư mục để xem nó có hoạt động không:

if [ ! -d ~/Desktop ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

Lý do cho nó là mở rộng dấu ngã chỉ hoạt động khi nó không được trích dẫn.

info "(bash) Tilde Expansion"

3.5.2 Tilde Expansion
---------------------

If a word begins with an unquoted tilde character (`~'), all of the
characters up to the first unquoted slash (or all characters, if there
is no unquoted slash) are considered a TILDE-PREFIX.  If none of the
characters in the tilde-prefix are quoted, the characters in the
tilde-prefix following the tilde are treated as a possible LOGIN NAME.
If this login name is the null string, the tilde is replaced with the
value of the `HOME' shell variable.  If `HOME' is unset, the home
directory of the user executing the shell is substituted instead.
Otherwise, the tilde-prefix is replaced with the home directory
associated with the specified login name.

Làm thế nào về nếu giá trị đến trong động. Tức là ( pastie.org/4471350 ) và DESTINATION~/Desktop.
Justin

3
Mở rộng Tilde được thực hiện khi biến được đặt, không phải khi nó được đánh giá, vì vậy đó không phải là một ví dụ công bằng.
MadHatter hỗ trợ Monica

+1, điều này là đủ để giải quyết vấn đề của tôi.
Bay Fisher

4

Nó không hoạt động không chỉ trên Mac mà trên bất kỳ nền tảng nào chạy bash trên.

Khi bạn trích dẫn "~ / Desktop", bạn đang nói bash hãy tìm Desktop trong thư mục ~. Các trích dẫn loại bỏ mục đích đặc biệt của ~

Xem - http://www.gnu.org/software/bash/manual/bashref.html#Tilde-Expansion

Xóa dấu ngoặc kép và nó sẽ hoạt động.


1

chạy

echo $HOME

sử dụng $HOMEvà đảm bảo rằng người dùng thực sự đang sử dụng tập lệnh. nếu root sử dụng ~nó sẽ nhìn vào /root, không /home/$USER.

if [ ! -d "$HOME/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

-1
if [ ! -d "$HOME/Desktop" ]; then
   echo "DOES NOT EXIST"
   exit 1;
fi

nên là $ HOME thay vì ~

~ là một điều TỪ KHÓA


Nếu bạn đọc câu trả lời khác ở đây, bạn sẽ nhận ra điều này là sai.
gà con
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.