Tên máy chủ tự động điền cho SSH và SCP


61

Tôi có một vài máy chủ được cấu hình ~/.ssh/config, chẳng hạn như alphabeta. Làm thế nào tôi có thể cấu hình Bash sao cho các lệnh ssh al<tab>scp file.tgz al<tab>tự động hoàn thành tên của các máy chủ được cấu hình?

Tôi không muốn thêm các máy chủ vào một tệp khác (tức là mảng Bash) mỗi lần được thêm vào, vì chúng tôi thêm và xóa máy chủ thường xuyên và danh sách khá lớn.


2
Bạn đã cài đặt gói bash-hoàn thành cho bản phân phối của mình chưa? Tôi nghĩ rằng đây là một phần của thói quen hoàn thành tiêu chuẩn mặc dù tôi có thể nhầm lẫn nó với zsh.
Caleb

Cài đặt của tôi làm chính xác điều này.
slm

Đây là trên Kubfox 12.10 và tôi đã bash-completioncài đặt.
dotancohen

Câu trả lời:


64

Tìm thấy rồi!!

Có vẻ như trong Ubuntu các mục trong ~/.ssh/known_hostsđược băm , vì vậy hoàn thành SSH không thể đọc chúng. Đây là một tính năng, không phải là một lỗi. Ngay cả bằng cách thêm HashKnownHosts novào ~/.ssh/config/etc/ssh/ssh_configtôi không thể ngăn chặn việc băm máy chủ.

Tuy nhiên, các máy chủ mà tôi quan tâm cũng được tìm thấy trong ~/.ssh/config. Đây là một kịch bản cho Bash Hoàn thành đọc các mục từ tệp đó:

_ssh() 
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts=$(grep '^Host' ~/.ssh/config ~/.ssh/config.d/* 2>/dev/null | grep -v '[?*]' | cut -d ' ' -f 2-)

    COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
    return 0
}
complete -F _ssh ssh

Đặt tập lệnh đó vào /etc/bash_completion.d/sshvà sau đó lấy nó bằng lệnh sau:

$ . /etc/bash_completion.d/ssh

Tôi thấy hướng dẫn này là vô giá và tôi sẽ không thể viết kịch bản này nếu không có nó. Cảm ơn Steve Kemp đã viết hướng dẫn tuyệt vời đó!


1
Có vẻ như trong Centos 6 mục trong ~ / .ssh / know_hosts các mục quá mức trong ~ / .ssh / config, vd. nếu bạn có foo.bar.baz.com trong know_hosts thì nó sẽ khớp với toàn bộ nếu bạn thực hiện "ssh foo" <tab> - điều này là không mong muốn nếu bạn có một người dùng khác hoặc các cài đặt khác mà bạn muốn áp dụng từ ssh confg. Nếu bạn có một mục trong cấu hình ssh không tự động hoàn thành đúng thì hãy kiểm tra xem nó có hiện diện trong know_hosts không và xóa nó. Bây giờ nó sẽ hoạt động như bình thường lấy các cài đặt từ cấu hình.
Imran-UK

@ Imran-UK: Người ta biết rằng Ubuntu không làm điều hợp lý đó, dưới sự giả vờ bảo mật. Rõ ràng người ta nghĩ rằng một thực thể độc hại có thể, như người dùng, chỉnh sửa ~ / .ssh / config, mặc dù chmod 0600 trên thư mục. Này, tôi không phải là người đưa ra quyết định!
dotancohen

1
Tôi sử dụng zsh & oh-my-zsh, tôi mới phát hiện ra rằng việc kích hoạt plugin "ssh" và đặt "HashKnownhosts yes" trong ~ / .ssh / config của tôi dường như làm đúng. Bạn có thể thay đổi vỏ bất cứ thứ gì bản phân phối để đây có thể là một cách xung quanh nó.
Imran-UK

@ Imran-UK: Thực tế tôi đã từng thử zsh trong quá khứ và tôi có ý định thử lại lần nữa. Tôi sẽ xem xét điều đó. Shukran bạn của tôi!
dotancohen

Tôi biết tôi đến bữa tiệc muộn một chút, nhưng RHEL 7 sẽ tự động hoàn thành các mục trong đó /etc/hosts, các bản phát hành khác có thể làm tương tự.
Centimane

16

Đóng gói sẵn

Bạn không nói những gì bạn đang sử dụng nhưng trên hệ thống Fedora 19 của tôi, tôi đã cài đặt gói sau, bash-completioncung cấp tính năng này thông qua tệp quy tắc hoàn thành này:

/usr/share/bash-completion/completions/ssh

Đây là gói tôi đã cài đặt:

$ rpm -aq |grep completion
bash-completion-2.1-2.fc19.noarch

Nếu bạn xem qua tệp quy tắc đó, bạn sẽ thấy các khổ thơ đang thẩm vấn $HOME/.ssh/configtệp:

$ grep config /usr/share/bash-completion/completions/ssh
    local configfile
    local -a config
        # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
                    configfile="$(dequote "${1:2}")"
                    [[ $1 ]] && configfile="$(dequote "$1")"
        _known_hosts_real -a -F "$configfile" "$cur"
    local configfile
        # Search COMP_WORDS for '-F configfile' argument
                    configfile="$(dequote "${1:2}")"
                    [[ $1 ]] && configfile="$(dequote "$1")"
        _known_hosts_real -a -F "$configfile" "$cur"
    local configfile prefix
        # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument
                    configfile="$(dequote "${1:2}")"
                    [[ $1 ]] && configfile="$(dequote "$1")"
                _known_hosts_real -c -a -F "$configfile" "$cur"

Cán của riêng bạn

Tôi cũng tìm thấy Gist này, know_hosts_autocomplete.sh , thực hiện một cái gì đó tương tự ngoại trừ với $HOME/.ssh/known_hoststệp.

# add to ~/.bash_profile, and close/reopen a shell.  Will autocomplete any
# hosts found in known_hosts.

complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | \
    sed -e s/,.*//g | uniq | grep -v "\["`;)" ssh

Bạn có thể làm điều gì đó tương tự bằng cách sử dụng $HOME/.ssh/configtệp của mình nếu vì một lý do nào đó bạn không thể tìm thấy tệp quy tắc hoàn thành cho việc sshđóng gói sẵn.


Cảm ơn bạn. Có vẻ như Ubuntu không giao hàng với /usr/share/bash-completion/completions/ssh. Bạn có thể gửi toàn bộ tập tin ở đâu đó mà tôi có thể sao chép nó không? Cảm ơn!
dotancohen

Bạn có thể lấy tất cả các tệp từ kho lưu trữ này: pkgs.fedoraproject.org/repo/pkgs/bash-completion/ Lỗi
slm

Tôi xin lỗi vì đã làm tôi đau, nhưng thậm chí còn sao chép tệp ssh từ kho lưu trữ tar đó để /usr/share/bash-completion/completions/sshkhông giúp ích! Không chạy complete -W ...lệnh từ dấu nhắc Bash. Điều gì có thể là vấn đề ở đây?
dotancohen

Cảm ơn bạn. Đây dường như là một quyết định thiết kế đã biết trong Ubuntu. Vì vậy, tôi chấp nhận câu trả lời mặc dù tôi không thể hoàn thành bash làm việc cho sshhoặc scp.
dotancohen

2
Homebrew cho OSX cũng có điều này: bash-hoàn thành và zsh-hoàn thành
Adam Nelson

7

Tôi thấy rằng tính năng tự động hoàn tất không hoạt động vì Ubuntu băm các máy chủ đã biết. Bạn có thể thêm

Host *
    HashKnownHosts no

Để .ssh/configtập tin của bạn nhưng máy chủ hiện tại sẽ không được băm.


Cảm ơn bạn. Tôi thực sự đã thêm chỉ thị này vào ~/.ssh/configvà thay đổi chỉ thị trong /etc/ssh/ssh_configvà tôi đã xóa ~/.ssh/known_hoststệp. Sau khi đăng nhập lại vào máy chủ, tên máy chủ vẫn đang được lưu băm.
dotancohen

Tôi đã chỉnh sửa câu trả lời của mình; bạn sẽ cần chỉ định một máy chủ lưu trữ và lồng lệnh băm bên trong; Tôi không liệt kê rằng nhiều .ssh/configtệp sẽ có dòng này. Cho tôi biết nếu nó hiệu quả.
M1ke

Đây chắc chắn là cách dễ dàng để làm điều đó! Cho rằng (phiên bản mới hơn) Ubuntu hiện đã kích hoạt hoàn thành ssh, đây có lẽ là điều mong muốn.
John Montgomery

Như tôi đã thêm bên dưới, bạn có thể làm điều này, nhưng có lẽ bạn không nên - bạn không cần phải hoàn thành công việc. Tuy nhiên, nếu bạn không đồng ý và chỉ muốn hủy băm các máy chủ hiện có sau khi thêm vào ở trên, bạn chỉ có thể rm ~ / .ssh / know_hosts và điều đó sẽ khiến nó được tạo lại (không băm) bất cứ khi nào bạn đăng nhập vào một máy chủ mới.
Jamieson Becker

3

Để bật tự động hoàn thành ssh trong Debian và Ubuntu:

sudo apt-get install bash-completion

Lưu ý rằng điều này hoàn toàn không liên quan gì đến băm đã biết_hosts, trái với những gì đã nêu ở trên và câu hỏi ban đầu. Nếu bạn muốn tự động hoàn tất từ ​​know_host, thì tất nhiên bạn sẽ phải vô hiệu hóa băm, nhưng điều đó được khuyến khích mạnh mẽ chống lại.

Ví dụ: tôi có:

Host *
    HashKnownHosts yes

trong .ssh / config của tôi và tôi vẫn có ssh tự động hoàn thành hoạt động tốt đối với các máy chủ được liệt kê trong .ssh / config và / etc / hosts. Bạn cần thêm máy chủ vào .ssh / config như OP đã nêu:

Lưu trữ tên máy chủ tuyệt vời của tôi Tên máy chủ the.real.host.name

(Hoặc, bạn có thể thêm mục nhập máy chủ vào / etc / hosts, đây là một nguồn khác cho tập lệnh Debian / Ubuntu.)

Sau đó, bạn có thể chỉ cần gõ ssh my-awe<tab>và nó sẽ được tự động hoàn thành. Một lần nữa, điều này là ngay cả khi bạn HashKnownhosts, rất được khuyến khích. (Lưu ý rằng việc hoàn thành bash cần được kích hoạt trong bash shell của bạn và bạn cần cài đặt cụ thể các tập lệnh như trên để phân phối.)

Sau đó, thêm các dòng này vào .bashrcđể kích hoạt nó (yêu cầu đăng xuất và đăng nhập lại hoặc chỉ cần bashnhập mới để khởi chạy shell mới. (Bạn không cần bật nếu nó đã được bật /etc/bash.bashrc/etc/profilenguồn /etc/bash.bashrc).

if [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
fi

Điều này sẽ cho phép tự động gõ ssh (trong số những thứ khác!) Từ ~/.ssh/config, /etc/hostsvv

Lưu ý rằng Debian mặc định là tro thay vì bash. Bạn có thể chuyển sang bash dễ dàng:

sudo usermod -s /bin/bash "$USER"

(Bạn sẽ cần phải đăng xuất và đăng nhập lại để việc này có hiệu lực.)


2

Trên Ubuntu 14.04, sshtự động hoàn tất các máy chủ được đề cập trong~/.ssh/config

Tôi nhận thấy điều đó khi tôi nhận ra rằng chỉ có một trong những máy chủ tôi thường truy cập tự động hoàn thành. Sự khác biệt duy nhất giữa hai là một mục trong tệp cấu hình ssh có liên quan đến xác thực. Khi tôi thêm một mục mới vào tệp cấu hình cho máy chủ khác, nó cũng bắt đầu tự động hoàn thành.

Đây là mục dành cho những người đang hỏi:

HOST server-name 
    GSSAPIAuthentication=no

Tôi sẽ rất ngạc nhiên nếu nó quan trọng những gì bạn đã chỉ định trong cấu hình (tất nhiên miễn là nó vẫn còn hiệu lực).


Cảm ơn bạn Nô-ê, mục đó là gì? Trên hệ thống 14.04 và 14.10 của tôi tự động hoàn tất không hoạt động.
dotancohen

Tôi không nghĩ mục nhập có vấn đề - tôi khá chắc chắn rằng nó chỉ có chúng trong đó - nhưng tôi sẽ thêm mục vào câu trả lời của mình.
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.