bash - cách chuyển kết quả từ lệnh nào sang cd


87

Làm cách nào để chuyển kết quả từ một whichlệnh sang cd?

Đây là những gì tôi đang cố gắng làm:

which oracle | cd
cd < which oracle

Nhưng không ai trong số họ hoạt động.

Có cách nào để đạt được điều này (tất nhiên thay vì sao chép / dán)?

Chỉnh sửa: theo suy nghĩ thứ hai, lệnh này sẽ không thành công, vì tệp đích KHÔNG phải là thư mục / thư mục .

Vì vậy, tôi đang suy nghĩ và tìm ra cách tốt hơn để loại bỏ phần "/ oracle" ở phía sau (sed hoặc awk, hoặc thậm chí Perl) :)

Chỉnh sửa: Được rồi, cuối cùng thì đó là những gì tôi có:

cd `which oracle | sed 's/\/oracle//g'`

2
mang đến cho bạn lệnh, không phải thư mục
Anycorn

Bạn đang cố lấy thư mục nơi chương trình được cài đặt? dirname, basename ?
Anycorn

@aaa: bạn là đúng, tôi nghĩ dirname là tốt hơn bởi vì nó trỏ đến "dir thực" không phải là một liên kết tượng trưng đến oracle thực thi ... đó là lý do apporach sed của tôi sẽ thất bại :)
Michael Mao

Câu trả lời:


128

Bạn sử dụng đường ống trong trường hợp lệnh mong đợi các tham số từ đầu vào chuẩn. ( Thêm về điều này ).

Với cdlệnh đó không phải là trường hợp. Thư mục là đối số lệnh. Trong trường hợp này, bạn có thể sử dụng thay thế lệnh. Sử dụng dấu gạch ngược hoặc $(...)để đánh giá lệnh, lưu trữ nó vào biến ..

path=`which oracle`
echo $path # just for debug
cd $path

mặc dù nó có thể được thực hiện theo cách đơn giản hơn nhiều:

cd `which oracle` 

hoặc nếu đường dẫn của bạn có các ký tự đặc biệt

cd "`which oracle`"

hoặc là

cd $(which oracle)

tương đương với ký hiệu backtick, nhưng được khuyến khích sử dụng (backticks có thể bị nhầm lẫn với dấu nháy đơn)

.. nhưng có vẻ như bạn muốn:

cd $(dirname $(which oracle))

(cho bạn thấy rằng bạn có thể sử dụng lồng nhau một cách dễ dàng)

$(...) (cũng như dấu gạch ngược) cũng hoạt động trong các chuỗi được trích dẫn kép, giúp khi kết quả cuối cùng có thể chứa khoảng trắng ..

cd "$(dirname "$(which oracle)")"

(Lưu ý rằng cả hai đầu ra đều yêu cầu một tập hợp các dấu ngoặc kép.)


Mát mẻ. Bạn có thể vui lòng giải thích một chút về những gì đang xảy ra ở đây? Điều đó trông giống như một tham chiếu biến; có một số biến tạm thời mặc định mà kết quả của một lệnh đi đến không?
Nate W.

Ahhh, tôi đã quên mất thuyết phục về backticks :(
Michael Mao

4
Bạn cần một cặp dấu ngoặc kép: cd "$(dirname "$(which oracle)")".
Philipp

Các |mở ra một quy trình mới, vì vậy ngay cả khi cdđọc từ STDIN, cmd | cdsẽ không làm việc (tức là thư mục hiện hành trong quá trình ban đầu sẽ vẫn như cũ).
Kyle Strand

23

Với dirname để lấy thư mục:

cd $(which oracle | xargs dirname)

CHỈNH SỬA: hãy cẩn thận với các đường dẫn chứa khoảng trắng, xem bình luận @anishpatel bên dưới


2
Sử dụng cd "$(which oracle | xargs -0 dirname)"nếu đường dẫn có thể chứa khoảng trắng. Cờ -0 phân chia đầu vào bằng null thay vì khoảng trắng.
anishpatel

9
cd `which oracle`

Lưu ý đó là những dấu gạch ngược (thường là phím ở bên trái số 1 trên bàn phím Hoa Kỳ)


1
Điều này không hoạt động nếu đường dẫn chứa khoảng trắng hoặc các ký tự "đặc biệt" khác và bạn phải loại bỏ tên tệp.
Philipp

@Philipp bạn có thể sử dụng điều này nếu đường dẫn của bạn có ký tự đặc biệtcd "`which oracle`"
Ram Patra

4

OK, đây là một giải pháp sử dụng trích dẫn chính xác:

cd "$(dirname "$(which oracle)")"

Tránh các dấu gạch chéo ngược, chúng khó đọc hơn và luôn trích dẫn các thay thế quy trình.


2

Bạn không cần một đường ống, bạn có thể làm những gì bạn muốn bằng cách sử dụng mở rộng tham số Bash!

Mẹo khác: sử dụng "type -P" thay vì lệnh "which" bên ngoài nếu bạn đang sử dụng Bash.

# test
touch /ls
chmod +x /ls
cmd='ls'
PATH=/:$PATH
if cmdpath="$(type -P "$cmd")" && cmdpath="${cmdpath%/*}" ; then
   cd "${cmdpath:-/}" || { echo "Could not cd to: ${cmdpath:-/}"; exit 1; }
else
   echo "No such program in PATH search directories: ${cmd}"
   exit 1
fi

1

Để trả lời câu hỏi đã chỉnh sửa của bạn, bạn có thể loại bỏ tên của lệnh bằng cách sử dụng dirname:

cd $(dirname `which oracle`)

Điều này không hoạt động nếu đường dẫn chứa khoảng trắng hoặc các ký tự "đặc biệt" khác.
Philipp

1
Dễ dàng sửa chữa bằng cách trích dẫn kép nó.
David Z

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.