Cách dễ nhất để thực hiện văn bản từ đuôi tại dòng lệnh là gì?


10

Đôi khi, tôi đang làm việc trên một hộp (ubfox) mới và tôi gõ gitvà được thông báo:

The program 'git' is currently not installed.  You can install it by typing:
apt-get install git-core

Nếu điều đó xảy ra tôi biết rằng tôi có thể lấy dòng cuối cùng bằng cách làm một cái gì đó như:

!! 2>&1 | tail -n 1

Nhưng làm thế nào tôi có thể thực hiện kết quả của điều đó ( apt-get install git-core) dễ dàng nhất?

Tôi nhận ra tôi có thể làm

`!! 2>&1 | tail -n 1`

Nhưng đó cũng là một cách để thực sự dẫn đầu ra và có được chạy không? Điều này dường như không hoạt động:

!! 2>&1 | tail -n 1 | sh

Ngoài ra 2>&1phần này hơi cồng kềnh nên tôi sẽ tò mò nếu có một cách dễ dàng hơn để làm điều đó xảy ra là tốt.

Biên tập

Cũng có thể chấp nhận lưu cái này vào một biến bằng cách nào đó và sau đó thực thi biến:

!! 2>&1 | tail -n 1 | (store as $mycmd)
$mycmd

Nhưng tôi không chắc chắn tôi biết một cách để stdoutchuyển thành một biến, ít nhất là không phải với biến nằm ở bên phải của lệnh.

Câu trả lời:


8

Khi bạn gõ lệnh không tồn tại trong hệ thống, bash sẽ chạy chức năng command_not_found_handle(). Trong chức năng này có một lệnh gọi /usr/lib/command-not-foundkịch bản in tin nhắn.

Ubuntu 12.04

Tôi đoán đầu tiên thay đổi nguồn của tập lệnh này để in tin nhắn stdoutthay vào đó stderr, nhưng khi tôi đang đọc nguồn tập lệnh, tôi thấy rằng bạn có thể định cấu hình nó để chỉ hỏi bạn nếu bạn muốn cài đặt gói bị thiếu.

Nếu bạn xuất biến, COMMAND_NOT_FOUND_INSTALL_PROMPTbạn sẽ được yêu cầu cài đặt gói bị thiếu:

pbm@ubuntu:~$ git
The program 'git' is currently not installed.  You can install it by typing:
sudo apt-get install git
pbm@ubuntu:~$ export COMMAND_NOT_FOUND_INSTALL_PROMPT=""
pbm@ubuntu:~$ git
The program 'git' is currently not installed.  You can install it by typing:
sudo apt-get install git
Do you want to install it? (N/y)y
sudo apt-get install git
[sudo] password for pbm: 

Các phiên bản cũ hơn của Ubuntu

Thật không may là không có COMMAND_NOT_FOUND_INSTALL_PROMPTvì vậy tôi có thể tìm thấy một vài lựa chọn khác:

1) Cài đặt gói từ 12.04 - không phải là vấn đề - chỉ có vài tập lệnh trong Python để nó hoạt động (chưa được kiểm tra!).

2) Thay đổi stderrthành stdout. Để làm điều đó, chỉnh sửa tập tin /usr/lib/python2.7/dist-packages/CommandNotFound/CommandNotFound.pyvà thay đổi stderrthành stdouttrong dòng 237 và 240.

Sau đó, bạn có thể sử dụng nó theo cách này:

pbm@ubuntu:~$ git
The program 'git' is currently not installed.  You can install it by typing:
sudo apt-get install git
pbm@ubuntu:~$ `git`
//Installation begins

Nếu bạn thêm -ytùy chọn vào apt-getlệnh trong dòng 237 và 240, bạn cũng có thể sử dụng cú pháp !! | sh.

3) Bạn cũng có thể sửa đổi tập lệnh này từ dòng 242 theo cách này:

print >> sys.stderr, _("You can install it by typing:")
f = open("%s/.install-missing" % os.path.expanduser('~'),'w')
print >> sys.stderr, "sudo apt-get install %s" % packages[0][0]
print >> f, "sudo apt-get install %s" % packages[0][0]
f.close()

Theo cách này, bạn sẽ nhận được lệnh của mình trong tệp ~/.install-missing, vì vậy bạn có thể tạo bí danh:

alias im="chmod +x ~/.install-missing; ~/.install-missing"

Nếu bạn gọi imgói sẽ được cài đặt.


Hmm, điều này trông thực sự tốt nhưng thực sự dường như không hoạt động trên 11.10 một chiều, /usr/lib/command-not-foundnhưng không có liên quan đến COMMAND_NOT_FOUND_INSTALL_PROMPT- suy nghĩ?
cwd

Ok, có vẻ như đây là một tính năng sẽ là một phần của 12.04 chính xác, ( pack-import.ub Ubuntu.com/diffs/command-not-found ). Tôi đoán tôi vẫn cần một giải pháp cho các phiên bản trước.
cwd

@cwd: Tôi đã cập nhật câu trả lời của mình ...
pbm

3

Bạn đã đi đúng hướng với:

!! 2>&1 | tail -n 1 | sh

... nhưng bạn đang thiếu một tùy chọn để sh . Xem xét:

!! 2>&1 | tail -n 1 | sh -s

Và vì bạn có thể cần quyền truy cập root để chạy apt-get, hãy xem xét:

!! 2>&1 | tail -n 1 | sudo sh -s

Điều này không hoạt động. sh và sh -s làm điều tương tự, ít nhất trong trường hợp này.
Deepak Găngal

1

Bạn có thể làm một cái gì đó như thế này:

!! 2>&1 | tail -n 1 > /tmp/cmd; bash /tmp/cmd; rm /tmp/cmd

Các chương trình tương tác dường như không hoạt động tốt với đường ống vì nó mong đợi một đầu vào, 'Y' trong trường hợp này, nhưng bộ mô tả tệp stdin bị đóng ngay khi lệnh đầu tiên kết thúc.


0

Bạn có thể sử dụng một biến evalvà thay thế lệnh tôi tin (mặc dù tôi không chắc tất cả sẽ an toàn đến mức nào):

TEST_VAR=$(!! 2>&1 | tail -n 1); eval $TEST_VAR

Tôi sẵn sàng để được chứng minh là sai với những điều trên. Tôi đang thử nghiệm điều này trên máy Red Hat bằng một echolệnh thay vì tự động hoàn thành bash đề xuất nhưng nguyên tắc nên giống nhau.

Vào cuối ngày, sẽ nhanh hơn khi chỉ cần gõ aptit cài đặt ...

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.