시스템에 로그인 할 때 bash readline을 vi 모드로 자동 설정하는 방법은 무엇입니까? 실제로 입력하지

우리 팀은 수천 대의 Linux / Unix 머신을 담당하므로 루트 계정은 당연히 관리자간에 “공유”됩니다. 나는 vi 모드를 선호하고, 다른 사람들은 emacs 모드를 선호합니다.

다른 사람이 vi 모드를 사용하지 않고 SSH를 로그인 할 때 bash의 readline을 vi 모드로 설정하려면 어떻게해야합니까?

본질적으로 set -o vi매번 실제로 입력하지 않고 다른 사람들에게 강제로 입력하지 않고 로그인 후 효과를 원합니다 (emacs 모드가 나에게 성가신 것처럼 vi 모드는 그들에게 성가시다).

모든 사람이 sudo와 함께 자신의 계정을 사용하여 권한있는 명령을 실행하는 경우 이것이 문제가되지 않는다는 것을 알고 있지만, 통제 할 수없는 상황으로 인해 슬프게도 옵션이 아닙니다.



답변

공개 키 인증에서만 잘 작동하는 바보 같은 방법이 있습니다.

먼저 로컬 머신이 있는지 확인 nc하십시오.

둘째, 여전히 로컬 컴퓨터에서 스크립트를 작성하고 (내가 전화 할 것입니다. connect-to-server) ${PATH}* 알고 있는 곳에 두십시오 .

#!/bin/sh
# connect-to-server
ssh -q server-hostname "touch .yourname" </dev/null >/dev/null 2>&1
nc server-hostname 22

다음으로, .bashrc원격 시스템에서 다음을 포함하도록 수정하십시오 .

# partial .bashrc
if [ -f "${HOME}/.yourname" ]; then
  rm "${HOME}/.yourname"
  set -o vi
fi

마지막으로 로컬 컴퓨터로 돌아가서 다음 ~/.ssh/config을 추가하여 편집 하십시오.

# partial ssh config
Host serverNickname
  Hostname server-hostname
  ProxyCommand connect-to-server

이 접근법의 단점 (그리고 내가 바보라고 부르는 이유) :

  • 실제 프록시 명령이 필요한 경우 더 복잡해집니다.
  • 다른 사람이 로그인하는 것과 동시에 로그인하면 .yourname파일이 아직 삭제되지 않았을 가능성이 set -o vi있습니다.
  • 당신이 경우에 가장 중요한 것은, ssh serverNickname command다음 command(이후 실행 하겠지만 .bashrc공급되지 않습니다)가 .yourname이 의사 프록시를 사용하지 않는 ssh를 설정에서 두 번째 별명을 가지고 정중 될 수 있도록, 파일 유적.

실제로이 방법 의 유일한 장점은 ssh명령에 추가 인수를 제공 할 필요가 없다는 것입니다.


* 원격 시스템에서 아무것도 변경하지 않으려는 경우 임시 의사를 생성하는 대체 의사 프록시가 있습니다 .bashrc.

#!/bin/sh
# connect-to-server
ssh -q server-hostname 'ln .bashrc .bashrc.real; cat .bashrc.real <(printf "set -o vi; ln -f .bashrc.real .bashrc\n") >.bashrc.yourname; ln -f .bashrc.yourname .bashrc' </dev/null >/dev/null 2>&1
nc server-hostname 22

이것은 다른 방법과 동일한 단점이 있으므로 ssh의사 프록시를 호출하지 않는 구성 의 두 번째 별칭을 계속 원할 것 입니다.


답변

나는 갈 것이다 :

ssh server -t "bash --login -o vi"

그러나 그것은 당신이 관리자입니다, 당신은 더 깨끗한 것을 시도 할 수 있습니다. 예를 들어 SendEnv, 클라이언트 측 에서 ssh 옵션을 사용하여 특정 변수를 전송 AcceptEnv하고 sshd구성 (서버 측) 에서 사용 하여 변수 를 승인 한 후이를 기반으로 .bashrc변수의 값에 따라 동작을 조정 하도록 루트 파일을 수정할 수 있습니다.

이는 sshd모든 호스트 의 구성과 호스트 의 구성 을 변경하는 것을 의미합니다 .bashrc. 그러나 “독립적 인”방법은 아닙니다.


답변

쉬운 클라이언트 측 솔루션 :

alias connect='ssh -t root@server "bash -o vi"'

이 실패합니다 루트의 쉘 초기화 스크립트를 명시 적으로 사용 set -o emacs또는 세트 EDITORemacs, 또는 루트의 경우 .initrc파일가 호출하는 emacs키 바인딩.

이 답변의 나머지 부분은 서버 측 솔루션에 관한 것입니다.


이것은 ssh기계에 들어가서 다음을 사용할 때 작동 합니다 sudo -i.

당신을 위해 /root/.bashrc:

if [[ -n "$SUDO_USER" ]] && [[ -f /root/.bashrc-"$SUDO_USER" ]]; then
  source /root/.bashrc-"$SUDO_USER"
fi

이를 통해 원하는대로 무엇이든 할 수 있는 개인 bashrc파일 을 가질 /root/.bashrc-patrick수 있습니다 set -o vi.

이것을 다음과 같이 rc 파일을 선택하는 다소 순진한 접근 방식과 결합하십시오 $SSH_CLIENT.

if [[ -n "$SUDO_USER" ]]; then
  person="$SUDO_USER"
elif [[ -n "$SSH_CLIENT" ]]; then

  case "$SSH_CLIENT" in
    192.168.216.100*)  person="joe" ;;
    192.168.216.120*)  person="patrick" ;;
    192.168.216.150*)  person="lindsey" ;;
  esac

fi

if [[ -n "$person" ]] && [[ -f /root/.bashrc-"$person" ]]; then
  source /root/.bashrc-"$person"
fi

이것은 항상 동일한 IP 주소에서 연결하는 경우에만 작동합니다 …

사용중인 특정 SSH 키의 설명 필드를 사용하는 또 다른 방법은 SSH 에이전트를 서버로 전달하는 경우 작동합니다.

ssh_comment="$( ssh-add -L | grep -f /root/.ssh/authorized_keys | awk '{ print $NF '} | head -n 1 )"

서버에 연결하는 데 사용한 키의 설명 필드를 선택합니다. 은 head -n 1당신이 당신의 키의 몇 가지가 일어날 경우에이 authorized_keys파일을.

그런 다음 위 $ssh_comment$SUDO_USER접근 방식 과 마찬가지로 (주석 $ssh_comment이 경로 이름 인 경우 정리가 필요할 수 있음) 접근 방식 case과 같은 명령문을 통해 소스로 rc 파일을 선택하는 데 사용할 수 있습니다 $SSH_CLIENT.


답변

서버 측에서 수정하지 않고 실제로 수행하려면 다음 중 하나를 수행하십시오.

1) 다음과 같은 것을 실행하십시오.

$ ssh user@host -t 'bash -l -o vi' 

나는 그 문서 가 너무 명확 하지 않다고 생각 하지만 -o option언급되어 작동하는 것 같습니다.

2) 사용 예상 :

expect스크립트 :

$ cat bashsetup.expect
#!/usr/bin/expect -f 

set user [lindex $argv 0];
set host [lindex $argv 1];

spawn ssh -l $user $host
expect "$ "
send "set -o vi\n"
interact

실행 가능하게 만들고 다음을 실행하십시오.

$ ./bashsetup.expect user testhost
spawn ssh -l user testhost
[motd, blahblah...]
user@testhost ~$ set -o vi
user@testhost ~$ 

이것은 원격 호스트 나 키에 암호를 입력하지 않고 로그인 할 수 있다고 가정합니다. 그렇지 않으면 expect 스크립트가 암호를 고려해야합니다. 그러나 많은 기계를 사용하면 이미 가지고있을 것입니다. 또한 달러 기호와 공백이 필요할 것으로 예상 되므로 프롬프트에 따라 편집하십시오 "# ".

프롬프트 전에 인쇄 된 내용에 동일한 문자가 포함되어 있으면 예상되는 문자열에보다 구체적인 내용을 포함해야합니다.

또한 해당 스크립트는에 대한 추가 인수 제공을 지원하지 않습니다 ssh. 명시적인 명령을 실행하려면 vi 모드가 필요하지 않지만 포트 터널링이 필요한 경우 문제가 될 수 있습니다.


그러나 어쨌든, 나는 이것이 별도의 계정 ( sudo또는 평범한 오래된 UID 0)을 가진 대상 시스템에서 해결되어야한다고 생각합니다 . 개인화 된 구성은 다른 많은 경우에도 유용하며 일반적으로 설정하려는 구성 파일과 환경 변수가 많이 있습니다. (관리자가의 값 $EDITOR이나 내용에 동의하지 않을 수도 있습니다 virc.)

또한 별도의 계정으로 사용자를 제거하는 것이 더 쉬울 것입니다.

모든 호스트에서 파일을 동기화하는 어떤 방법도 하찮게 같은로 로그인을 허용함으로써이 문제를 해결 것 ssh -t user@host 'patricks_shell.sh'ssh -t user@host 'bash --rcfile patrick.rc'.


답변

이 안내서에 따라 사용자 정의 rc 파일을 가질 수 있습니다.

사용자 rc 파일 | 보안 셸 : 결정적인 가이드

authorized_keys 파일에 명령 행 조치를 삽입하십시오.

SSH 구성 자동 실행 원격 명령 | 유닉스 및 리눅스 스택 교환