Chạy script từ thư mục khác


11

Rất thường xuyên, tập lệnh tôi muốn thực thi không nằm trong thư mục làm việc hiện tại của tôi và tôi không thực sự muốn rời khỏi nó.

Có phải là một thực hành tốt để chạy các tập lệnh (BASH, Perl, v.v.) từ một thư mục khác? Họ thường sẽ tìm thấy tất cả những thứ họ cần để chạy đúng không?

Nếu vậy, cách tốt nhất để chạy một kịch bản "xa" là gì? Là nó

. /path/to/script

hoặc là

sh /path/to/script

và làm thế nào để sử dụng sudotrong những trường hợp như vậy? Điều này, ví dụ, không hoạt động:

sudo . /path/to/script

Hãy nhận biết rằng . /path/to/script các nguồn kịch bản! Bạn hoàn toàn không cần thời gian nếu bạn chỉ muốn chạy nó.
gniourf_gniourf

Câu trả lời:


14

sh / path / to / script sẽ sinh ra một shell mới và chạy script script độc lập với shell hiện tại của bạn. Lệnh source(.) Sẽ gọi tất cả các lệnh trong tập lệnh trong trình bao hiện tại. Nếu kịch bản xảy ra để gọi exitchẳng hạn, thì bạn sẽ mất trình bao hiện tại. Do đó, thường an toàn hơn khi gọi các tập lệnh trong một shell riêng bằng sh hoặc thực thi chúng dưới dạng nhị phân bằng cách sử dụng đường dẫn đầy đủ (bắt đầu bằng /) hoặc đường dẫn tương đối (./). Nếu được gọi là nhị phân, chúng sẽ được thực thi với trình thông dịch được chỉ định (chẳng hạn #! / Bin / bash).

Vì để biết liệu một tập lệnh có tìm thấy các tập tin mà nó cần hay không, không có câu trả lời hay, ngoài việc nhìn vào tập lệnh để xem nó làm gì. Như một tùy chọn, bạn luôn có thể chuyển đến thư mục của tập lệnh trong quy trình phụ mà không cần rời khỏi thư mục hiện tại của mình:

$(cd /wherever/ ; sh script.sh)

3
Ý bạn là (cd /wherever/ ; sh script.sh)sao Tại sao bạn có một $ở phía trước?
G-Man nói 'Phục hồi Monica'

7

Bạn chắc chắn có thể làm điều đó (với các điều chỉnh mà những người khác đã đề cập như sudo sh /pathto/script.shhoặc ./script.sh). Tuy nhiên, tôi làm một trong một vài điều để chạy chúng trên toàn hệ thống để không lo lắng về các thư mục và giúp tôi tiết kiệm thêm việc gõ.

1) Liên kết đến /usr/bin

ln -s /home/username/Scripts/name.sh /usr/bin/name

(hãy chắc chắn rằng không có tên trùng lặp ở đó, vì rõ ràng bạn sẽ ghi đè lên nó.) Điều này cũng cho phép tôi giữ chúng trong các thư mục phát triển của mình để tôi có thể điều chỉnh khi cần thiết.

2) Thêm thư mục ScScript vào đường dẫn của bạn (sử dụng .bash_profile - hoặc anything.profile bạn có trên trình bao của mình)

PATH=/path/to/scripts/:$PATH

3) Tạo bí danh trong phần thêm .bash_profile vào ~/.bash_profilenhư:

alias l="ls -l"

Như bạn có thể nói, cú pháp chỉ là bí danh, chữ số bạn muốn đóng vai trò là lệnh, lệnh. Vì vậy, gõ "l" bất cứ nơi nào trong thiết bị đầu cuối sẽ dẫn đến ls -l Nếu bạn muốn sudo, chỉ cần alias sl="sudo ls -l"lưu ý cho chính mình l vs sl (như một ví dụ vô dụng).

Dù bằng cách nào, bạn chỉ có thể gõ sudo nameofscriptvà đang trên đường. Không cần phải lộn xộn với ./ hoặc. hoặc sh, v.v. Chỉ cần đánh dấu chúng là thực thi đầu tiên: D


Tôi rất muốn giới thiệu và tùy chọn 2.
Bernhard

Tại sao?, Đó là một thực hành tốt nhất hoặc chỉ là hương vị?
Sergio

3

Tôi thường làm như bạn nói

sh /path/to/script

Và để chạy nó như root / superuser

sudo sh /path/to/script

Thư mục hiện tại của bạn chỉ quan trọng nếu các tập lệnh giả định rằng bạn đang ở trong cùng thư mục với nó. Tôi cho rằng hầu hết các tập lệnh không làm điều này và bạn được lưu để chạy nó như trên.


sẽ không hoạt động nếu Secure_path được đặt trong tệp / etc / sudoers
l1zard

3

Tôi thường giữ các tập lệnh của mình trong /usr/local/binhoặc /usr/local/sbin/(nếu tập lệnh cần đặc quyền gốc), theo Tiêu chuẩn phân cấp hệ thống tập tin (FHS), chúng thuộc về.

Tất cả bạn phải làm là đảm bảo hai thư mục này được thêm vào của bạn PATH. Bạn có thể làm điều này bằng cách chỉnh sửa $HOME/.bashrctệp của bạn và thêm dòng này:

export PATH=$PATH:/usr/local/sbin:/usr/local/bin

Nếu bạn muốn có thể thực thi một tập lệnh như root thông qua sudo, bạn phải thêm các thư mục này vào biến secure_pathtrong của bạn /etc/sudoers.

Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

Chỉnh sửa tệp này được thực hiện bằng cách chạy visudođể đảm bảo bạn không có bất kỳ sai lầm nào.


Typo: ý bạn là .bashrcthay vì .bachrc.
gniourf_gniourf

0

Tôi không chắc nó hoạt động như thế này trong linux, giả sử nó không hoạt động nếu không có ai đề xuất. Nhưng thay vì sử dụng ././ để quay lại thư mục. Bạn có thể sử dụng dấu ngoặc kép để cung cấp cho nó một đường dẫn tuyệt đối? Có lẽ nó không cung cấp cho bạn quyền truy cập vào toàn bộ ổ đĩa để thậm chí có thể làm điều đó thực sự đến để nghĩ về nó.


0

Nếu bạn có các tập lệnh nằm xung quanh mà bạn cần chạy thường xuyên và chúng phụ thuộc vào vị trí của chúng để tìm tài nguyên, bạn có thể dễ dàng thực hiện việc này bằng cách kết hợp các lệnh trong một bí danh như thế này.

alias run-script="cd /home/user/path/to/script/ && bash script.sh"

Bằng cách này, bạn không phải thay đổi bất cứ điều gì khác để làm cho nó hoạt động.


0

Không chắc tại sao không ai đề xuất cái này, nhưng nó siêu dễ! Tôi đã Googled một vài lần và không thể tìm thấy câu trả lời chính xác này mà tôi đang đưa ra nên tôi nghĩ tôi muốn chia sẻ. IMO, đây là giải pháp tốt nhất, cũng là giải pháp dễ nhất, đối với tôi dù sao đi nữa, tuy nhiên những người khác có thể cảm nhận và làm mọi thứ khác đi.

# Place this somewhere in your .bashrc/.bash_profile/etc and edit as you see fit

YOURCOMMAND () {
  cd /path/to/directory/containing/your/script/ && ./YOURSCRIPT
}

Đầu tiên, lệnh 'cd' cho nó biết thư mục của vị trí tập lệnh. Sau đó '&&' để bạn có thể buộc nó sau khi thực hiện lệnh tiếp theo. Cuối cùng mở tập lệnh của bạn giống như bạn sẽ thực thi nó trong terminal! Đã lưu trong tệp BASH của bạn và mất 5 giây để thiết lập.

Hy vọng điều này đã giúp ai đó.


-1

Câu hỏi cổ xưa, nhưng một câu hỏi vượt thời gian.

Giải pháp mà tôi luôn thấy là có một $HOME/binthư mục và đặt nó vào trước $PATH(thông qua ~/.bashrcnếu nó chưa có ở đó; trên một số hệ thống ~/binđược đặt trước $PATHtheo mặc định). Bỏ tập lệnh vào đó để thực thi hoặc liên kết tượng trưng cho tập lệnh / tệp thực thi ở nơi khác là cách đơn giản để xử lý các sự cố đường dẫn không ảnh hưởng đến hệ thống hoặc người dùng khác.

Nếu một tập lệnh yêu cầu các tài nguyên bổ sung có thể được tìm thấy liên quan đến vị trí của chính nó (không phổ biến) thì envvar $BASH_SOURCEđược sử dụng. $BASH_SOURCEluôn chứa đường dẫn tuyệt đối đến chính tập lệnh hiện đang chạy, bất kể giá trị của $PWD.

Hãy xem xét những điều sau đây:

ceverett@burrito:~$ echo $PATH
/home/ceverett/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Vì vậy, chúng ta có thể thấy đó $HOME/binlà lần đầu tiên $PATH, vì vậy bất cứ điều gì tôi đặt vào ~/binsẽ chạy. Tôi có một kịch bản trình diễn được gọi là ~/bin/findme:

#!/bin/bash

echo "Running from $BASH_SOURCE"

Điều này có thể được sử dụng để có được đường dẫn tuyệt đối đến vị trí của tập lệnh đang chạy.

ceverett@burrito:~$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~$ cd foo
ceverett@burrito:~/foo$ findme
Running from /home/ceverett/bin/findme
ceverett@burrito:~/foo$ cd /
ceverett@burrito:/$ findme
Running from /home/ceverett/bin/findme

(1) Mặc dù đây có vẻ là thông tin hữu ích, nhưng câu hỏi không hỏi làm thế nào để viết các tập lệnh sử dụng tài nguyên liên quan đến vị trí của chúng; Nó hỏi về việc chạy script. (2) Tôi không chắc đoạn văn thứ hai của bạn giải quyết câu hỏi như thế nào. Bạn có gợi ý rằng, nếu tôi viết một kịch bản và Desmond muốn chạy nó, anh ta nên liên kết nó vào binthư mục riêng của mình ? Điều đó có vẻ rườm rà. (3) Ngoài ra, nó phá vỡ sự độc lập vị trí. Nếu /home/desmond/bin/foolà một liên kết đến tập lệnh của tôi thì BASH_SOURCEsẽ có /home/desmond/bin/foovà tập lệnh sẽ không thể tìm thấy tài nguyên của nó.
G-Man nói 'Phục hồi Monica'

@ G-Man (1) Người dùng không cung cấp nhiều ngữ cảnh. Bất cứ khi nào câu hỏi này được hỏi về tôi trong 30 năm qua, nó luôn nằm trong bối cảnh người dùng (thường là một sysop hoặc nhà phát triển mới) chạy hỗn hợp các tập lệnh riêng của mình và các tập lệnh thu được khác để tự động hóa các tác vụ tầm thường, vì vậy tôi đã trả lời rằng đường. Điều này không thừa nhận một chút kiến ​​thức về kịch bản từ phía người dùng yêu cầu. (2) Các tập lệnh toàn hệ thống thường được cài đặt tại /binhoặc một vị trí đã biết trong /opt. (3) Độc lập vị trí là chính xác những gì điều này bảo tồn khi viết một bộ sưu tập các tập lệnh cá nhân phụ thuộc lẫn nhau.
zxq9
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.