Sử dụng xác thực tương tác bàn phím khi đường ống ssh xuất ra lệnh khác


7

Tôi muốn chuyển đầu ra của ssh sang một lệnh khác. Ví dụ:

ssh myserver cat remote-file | diff local-file -

Vấn đề là myserver yêu cầu mật khẩu, nhưng tôi không thể nhập nó. (Vì một số lý do, xác thực khóa công khai không khả dụng trên máy chủ. Tôi không thể thay đổi điều này.) Tôi nhận được lời nhắc "Mật khẩu:", nhưng các khóa tôi nhập bị lặp lại và không được chuyển cho ssh. Làm thế nào tôi có thể làm cho ssh có được mật khẩu?

Lưu ý Tôi không cố gắng chuyển mật khẩu vào ssh . Tôi đang cố gắng chuyển đầu ra của ssh và nhập mật khẩu như bình thường.

Trong trường hợp có vấn đề, tôi đang sử dụng bash trên OS X 10.7 (Lion) và Terminal chuẩn. Tôi không có bí danh nào được thiết lập có thể gây ra điều này. Tôi đã thấy cùng một hệ thống khác nhau (Linux), vì vậy tôi tin rằng nó không cụ thể đối với thiết lập của tôi.


1
Bạn không nhận được cùng nếu bạn chạy ssh myserver cat remote-filemột mình? Bạn thấy gì khi bạn chạy nó sau set -x?
Stéphane Chazelas

Bạn có thấy testkhi nào echo test > /dev/ttykhông?
Stéphane Chazelas

@StephaneChazelas: Cảm ơn, ý kiến ​​của bạn đã giúp tôi tìm ra câu trả lời! Nếu tôi chạy ssh myserver cat remote-filemột mình nó hoạt động như mong đợi, cũng echo test > /dev/ttyhoạt động. Tuy nhiên, chạy với set -xnhổ ra một đống rác. Hóa ra tôi đã tùy chỉnh lời nhắc của mình để đặt tiêu đề cửa sổ thành lệnh hiện đang chạy. Điều đó đã tạo ra một nhánh con cho mọi lệnh và bằng cách nào đó đã làm hỏng điều này. Khi tôi nhận xét các dòng vi phạm, nó đã làm việc.
jdm

Câu trả lời:


4

OK, hóa ra điều này là do sự tương tác kỳ lạ với cấu hình bash của tôi.

Tôi có một cái gì đó trong .bash_profileđó đặt lệnh hiện được thực thi vào tiêu đề cửa sổ hoặc screentab. Nó hoạt động bằng cách sử dụng một trap:

trap 'bash_current_command' DEBUG

Và trước đó:

function bash_current_command {
    # only works in bash > 3.1
    #set -- $BASH_COMMAND

    # for old bash
    set -- $(history 1)
    shift

    if [[ "$1" == "sudo" ]]; then
        cmd="*$(basename -- "$2")*"
    else
        cmd="$(basename -- "$1")"
    fi

    bash_set_title "$cmd"
}

bash_set_titlelà một chức năng nhỏ đặt tiêu đề biểu tượng và tiêu đề của thiết bị đầu cuối hiện tại bằng cách sử dụng mã thoát ANSI. Như bạn có thể thấy, điều này tạo ra các subshells $(...), và trực giác của tôi nói với tôi rằng đây có thể là vấn đề. Thật vậy, sau khi tôi thay đổi những dòng đó, nó đã hoạt động!

Nếu ai đó biết tại sao điều này xảy ra, tôi rất vui khi biết chi tiết. Do subshells thường ăn cắp ttyđầu vào? Hay nó chỉ là một vấn đề trong một cái bẫy gỡ lỗi? Tôi không nhớ các vấn đề với stdinđầu vào / đường ống thông thường vào các lệnh.

(Như bạn cũng có thể thấy, dù sao cũng có một vài vấn đề với chức năng của tôi - nó sử dụng một trong các lớp con như một cách giải quyết để nó có thể chạy trên một phiên bản bash cổ (Tôi bị mắc kẹt trên hệ thống cũ, nhưng vẫn muốn một cấu hình hợp nhất). Subshell khác được sử dụng để trích xuất lệnh thực tế khi sử dụng sudo, nhưng điều này không thành công nếu sudo được gọi với các công tắc như sudo -H -u user command. Vì vậy, tôi sẽ coi đây là cơ hội để sửa mã này ...)


Nghe có vẻ như một lỗi trong bash. Với 3.0.16, tôi không sao chép của bạn, nhưng tôi thấy bash: child setpgid (24993 to 24990): Operation not permittedkhi chạy tên cơ sở. Sự nghi ngờ của tôi là sshcuối cùng không nằm trong nhóm quy trình tiền cảnh của thiết bị đầu cuối và do đó bị đình chỉ khi nó cố gắng vô hiệu hóa tiếng vang, đó là lý do tại sao bạn có thể thấy mật khẩu bị lặp lại của mình. Nhật ký của một strace -fsẽ cho chúng tôi biết thêm.
Stéphane Chazelas

2

Câu trả lời này không giải thích vấn đề cụ thể của bạn nhưng cung cấp một số cách giải quyết có thể có khả năng giúp cuộc sống của bạn thuận tiện hơn.

Nếu bạn chỉ sử dụng ssh để truy cập các tệp từ xa và không chạy các lệnh từ xa, thì bạn có thể gắn hệ thống tệp từ xa thông qua sshfs . Bạn sẽ cần cài đặt FUSE cho OS XSSHFS trước. (Tôi không biết nếu có phân phối nhị phân cho OSX.) Sau đó chạy

mkdir ~/myserver
sshfs myserver:/ ~/myserver

Bạn sẽ chỉ cần xác thực khi bạn chạy sshfslệnh. Sau đó, các tệp từ xa có sẵn ~/myserver, vì vậy bạn có thể làm diff ~/myserver/path/to/remote-file local-filemà không phải lo lắng rằng một trong các tệp đó là từ xa. Chạy fusermount -u ~/myserverđể ngắt kết nối hệ thống tập tin.

Một cách tiếp cận khác cho phép bạn xác thực một lần và sau đó chạy nhiều lệnh ssh là thiết lập kết nối chính. Xem Sử dụng lại phiên ssh cho các lệnh rsync lặp lại

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.