Có cách nào để thực thi một lệnh trong một thư mục khác mà không cần phải thực cd
hiện nó không? Tôi biết rằng tôi có thể chỉ đơn giản là cd
trong và cd
ra ngoài, nhưng tôi chỉ quan tâm đến các khả năng của ít ưu điểm hơn các bước thêm :)
Có cách nào để thực thi một lệnh trong một thư mục khác mà không cần phải thực cd
hiện nó không? Tôi biết rằng tôi có thể chỉ đơn giản là cd
trong và cd
ra ngoài, nhưng tôi chỉ quan tâm đến các khả năng của ít ưu điểm hơn các bước thêm :)
Câu trả lời:
Tôi không biết nếu điều này được tính, nhưng bạn có thể tạo một subshell:
$ (cd /var/log && cp -- *.log ~/Desktop)
Thư mục chỉ được thay đổi cho lớp con đó, vì vậy bạn tránh được công việc cần thiết cd -
sau đó.
$ (cd /var/log && cp *.log ~/Desktop)
. Theo cách đó, nếu thư mục không tồn tại, không có lệnh nào được thực thi nữa.
Một số chương trình có các tùy chọn mà bạn có thể yêu cầu chúng tự chdir (2) (ví dụ: GNU tar tựa s -C
/ --directory
).
Mặc dù bên ngoài các chương trình như vậy, một cái gì đó sẽ phải chdir . Bạn có thể viết và sử dụng một số loại chương trình BST nhị phân được biên dịch thay vì sử dụng shell, nhưng có lẽ nó sẽ không mang lại nhiều lợi ích.
Trong một bình luận trong một câu trả lời khác, bạn đã đưa ra một ví dụ:
execindirectory -d /var/log "cp *.log ~/Desktop"
Vì *.log
mẫu được mở rộng bằng chính shell (không phải cp ), nên một cái gì đó sẽ phải chdir vào thư mục trước khi có shell đánh giá lệnh của bạn.
Nếu bạn chỉ thú vị trong việc tránh phải quay lại cd cd, thì bạn có thể sử dụng một lớp con để tách hiệu ứng của cd khỏi thể hiện vỏ làm việc của bạn.
(cd /path/to/dir && some command)
Bạn có thể gói nó trong một hàm shell. (Tôi đã bỏ -d
tùy chọn khỏi cách sử dụng ví dụ của bạn vì có rất ít điểm đến lệnh này nếu thư mục thực sự là tùy chọn.)
runindir() { (cd "$1" && shift && eval "$@"); }
runindir /var/log 'cp *.log ~/Desktop' # your example
runindir /var/log cp \*.log \~/Desktop # eval takes multiple args
runindir /var/log cp \*.log ~/Desktop # it is okay to expand tilde first
Không làm giảm giá trị của câu trả lời được đưa ra bởi người khác, nhưng tôi tin rằng những gì bạn muốn là đây:
(cd /path/to && ./executable [ARGS])
Lưu ý các parens để gọi cd
trong một vỏ phụ.
Đây là một cái gì đó sẽ cho phép bạn cd
trở lại nơi bạn đã ở (sử dụng Bash), vì không quên làm như vậy dường như là mục đích của câu hỏi:
# Save where you are and cd to other dir
pushd /path/to/dir/that/needs/to/be/current/dir
run-your-command
# Get back where you were at the beginning.
popd
(EDIT: phiên bản ngắn hơn một chút, nhờ @ Random832)
pushd other-dir
, chứ không phảipushd .; cd other-dir
Đáng buồn thay, ví dụ của bạn:
execindirectory -d /var/log "cp *.log ~/Desktop"
không cần thay đổi thư mục, bởi vì
cp /var/log/*.log ~/Desktop
sẽ làm như vậy. Bạn có thể đến gần hơn với vấn đề thực sự của bạn? Bởi vì chúng ta có thể biết một giải pháp tốt hơn cho điều đó quá.
Một cách phức tạp để giải quyết vấn đề của bạn, khác xa với sự thanh lịch của giải pháp Michaels, là sử dụng công cụ tìm kiếm, có công tắc '-execdir' được thực hiện trong thư mục, nơi tìm thấy tệp. Áp dụng không tốt cho ví dụ của bạn:
find /var/log -maxdepth 1 -type f -name "*.log" -execdir echo cp {} ~/Desktop ";"
Có lẽ nó hữu ích cho vấn đề thực sự của bạn. -okdir thay vì -execdir sẽ yêu cầu bạn xác nhận mọi lời mời.
-okdir và -execdir có thể cần cài đặt gnu-find, thường được sử dụng trên Linux.
Thế còn ./your/path/command.sh
?
execindirectory -d /var/log "cp *.log ~/Desktop"
.
echo "#!/bin/bash; cd $1; exec $2" > /usr/local/bin/execindirectory; chmod +x /usr/local/bin/execindirectory
. Có thể cần nỗ lực hơn một chút nếu bạn muốn nó thực sự hỗ trợ các "thẻ" tùy chọn, chẳng hạn như-d
và công cụ.