Các tệp bí danh Symlink trong thư mục con mà không thay đổi thư mục hiện tại


11

Có vẻ như thật đơn giản để liên kết một tệp với một tệp mới trong thư mục con .... .... mà không di chuyển các thư mục con. Nhưng một cái gì đó về cú pháp là bối rối và phản lại những gì tôi mong đợi. Đây là một trường hợp thử nghiệm:

mkdir temp
cd temp
mkdir deploy
echo "Contents of the build file!" > deploy/resources.build.php
ln -s deploy/resources.build.php deploy/resources.php
cat deploy/resources.php #bad symlink

Điều này chỉ tạo ra một symlink bị hỏng! Tôi đang chạy cái này trong một kịch bản thiết lập môi trường xây dựng, vì vậy tôi muốn tránh thay đổi thư mục làm việc hiện tại nếu có thể.

ln -s deploy/resources.build.php resources.php
cat deploy/resources.php

Cũng không hoạt động vì nó tạo liên kết tượng trưng trong thư mục tạm thời thay vì thư mục con triển khai.

cd deploy
ln -s resources.build.php resources.php
cd ..

Điều này hoạt động, nhưng tôi muốn biết làm thế nào để làm điều đó mà không thay đổi thư mục.

Sử dụng một đường dẫn đầy đủ như:

/home/whatever/src/project/temp/stuff/temp/deploy/resources.build.php

Hoạt động, nhưng không phổ biến và hơi không thực tế, đặc biệt là trong môi trường xây dựng nơi tất cả các công cụ dự án có thể khác nhau giữa các bản dựng và tương tự.

Làm cách nào tôi có thể tạo một liên kết tượng trưng giữa hai tệp trong thư mục con, mà không di chuyển vào thư mục con đó và ra khỏi nó, và trong khi đặt cho tệp mới "bí danh" một tên mới?

Câu trả lời:


10

Nhưng một cái gì đó về cú pháp là bối rối và phản lại những gì tôi mong đợi.

Các đối số cho ln, ở dạng bạn đang sử dụng, là:

ln [TÙY CHỌN] ... [-T] TARGET LINK_NAME (mẫu thứ 1)

Các bối rối, điều unintuitive là khi bạn đang tạo ra một liên kết tượng trưng, các mục tiêu tranh luận cho lncó thể sẽ không là một đường dẫn đến một tập tin, nhưng đúng hơn là nội dung của liên kết tượng trưng được tạo ra. Nếu bạn nghĩ về nó một lúc, rõ ràng nó phải như vậy. Xem xét:

$ echo foo >foo
$ ln -s foo bar1
$ ln -s $PWD/foo bar2
$ cat bar1
foo
$ cat bar2
foo
$ ls -l bar1 bar2
lrwxrwxrwx 1 matt matt  3 Dec 29 16:29 bar1 -> foo
lrwxrwxrwx 1 matt matt 29 Dec 29 16:29 bar2 -> /home/matt/testdir/foo

Trong ví dụ đó, tôi tạo 2 liên kết tượng trưng, ​​được đặt tên là "bar1" và "bar2", trỏ đến cùng một tệp. lsTuy nhiên, cho thấy bản thân các liên kết tượng trưng có nội dung khác nhau - một liên kết chứa một đường dẫn tuyệt đối và một liên kết chứa một đường dẫn tương đối. Vì điều này, một người sẽ tiếp tục làm việc ngay cả khi nó được chuyển sang thư mục khác và thư mục kia sẽ không:

$ mv bar2 /tmp
$ cat /tmp/bar2
foo
$ mv bar1 /tmp
$ cat /tmp/bar1
cat: /tmp/bar1: No such file or directory

Vì vậy, xem xét rằng chúng ta phải có khả năng tạo cả hai liên kết tương đối và tuyệt đối và thậm chí để tạo các liên kết bị hỏng sẽ không bị phá vỡ nếu tệp mục tiêu được tạo sau đó, đối số đích phải được hiểu là văn bản dạng tự do, thay vì đường dẫn đến một tập tin đã tồn tại.

Nếu bạn muốn tạo một tệp có tên triển khai / resource.php liên kết đến triển khai / resource.build.php, bạn cần quyết định xem bạn có muốn tạo một liên kết tượng trưng tuyệt đối không (có khả năng chống lại liên kết tượng trưng được di chuyển, nhưng sẽ phá vỡ nếu mục tiêu được di chuyển) hoặc một liên kết tượng trưng tương đối (sẽ tiếp tục hoạt động miễn là cả liên kết tượng trưng và mục tiêu được di chuyển cùng nhau và duy trì các đường dẫn tương đối giống nhau).

Để tạo một liên kết tượng trưng tuyệt đối, bạn có thể làm:

$ ln -s $PWD/deploy/resources.build.php deploy/resources.php

Để tạo một tương đối, trước tiên bạn sẽ tìm ra đường dẫn tương đối từ nguồn đến đích. Trong trường hợp này, vì nguồn và đích nằm trong cùng một thư mục so với nhau, bạn chỉ có thể thực hiện:

$ ln -s resources.build.php deploy/resources.php

Nếu họ không ở trong cùng một thư mục, thay vào đó bạn cần phải làm một cái gì đó như:

$ ln -s ../foo/f bar/b

Trong trường hợp đó, mặc dù foobarcả hai đều nằm trong thư mục hiện tại của bạn, bạn cần đưa a ../vào ln mục tiêu vì nó mô tả cách tìm ftừ thư mục chứa b.

Đó là một lời giải thích cực kỳ dài, nhưng hy vọng nó sẽ giúp bạn hiểu lncú pháp tốt hơn một chút.


3

Bạn có thể tạo liên kết trong một khung con, như sau:

  (cd deploy && ln -s resources.build.php resources.php && cat resources.php)

Khi subshell kết thúc thực thi, bạn sẽ thấy mình vẫn ở trong thư mục chính xác.

Ngoài ra, bạn có thể thử

 ln -s resources.build.php deploy/resources.php

cũng hoạt động, bỏ qua việc đưa vào CL thực tế là tệp resource.build.php không có trong thư mục nơi bạn đang phát lệnh, nhưng thực tế là bên trong ./deploy .


Đây là ma thuật đen, thưa ngài!
Kzqai

1

Điều này làm tôi bối rối cho đến khi tôi nhận ra một symlink về cơ bản là một tập tin cấu hình. tức là làm thế nào tôi có thể ghi dữ liệu đường dẫn đó vào một tệp văn bản đơn giản:

ln -s [target] [link name]

trở thành:

echo [target] > [link name]

Các lỗi mà tôi (và có lẽ OP) đã làm là trong suy nghĩ ln nhu cầu biết về các tập tin đó là nhắm mục tiêu. Tôi không quan tâm. Nó chỉ viết một số thông tin đường dẫn vào một tập tin. Đây là một lệnh ln hoàn toàn hợp lý :

ln -s /path/doesnt/exist/file.err
ll
file.err -> /path/doesnt/exist/file.err

Vì thế:

ln -s deploy/resources.build.php deploy/resources.php

tạo ra một tệp simlink được gọi resources.phptrong ./deploythư mục tham chiếu tệp resources.build.phptrong thư mục ./deploy/deploy/.

Đó không phải là những gì bạn muốn và đưa ra một liên kết xấu (bị hỏng). Không có gì sai với liên kết, nếu bạn đặt tệp đó vào đó thì liên kết sẽ hoạt động. Tuy nhiên, (như được chỉ ra bởi những người khác) điều tôi và OP muốn là:

ln -s resources.build.php deploy/resources.php
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.