Как перевести bash readline в режим vi автоматически при входе в систему?

Есть еще один простой способ получить статистику проверки связи во время его выполнения: Просто нажмите Ctrl + | ( вертикальная косая черта или его также называют конвейерной линией)

Лично я использую его очень часто, попробуйте:

64 bytes from 192.168.1.1: icmp_seq=6 ttl=64 time=0.893 ms
64 bytes from 192.168.1.1: icmp_seq=23 ttl=64 time=0.862 ms
64 bytes from 192.168.1.1: icmp_seq=24 ttl=64 time=3.18 ms
64 bytes from 192.168.1.1: icmp_seq=35 ttl=64 time=0.877 ms
64 bytes from 192.168.1.1: icmp_seq=36 ttl=64 time=0.866 ms
**36/36 packets, 0% loss, min/avg/ewma/max = 0.832/0.993/0.930/3.185 ms**
64 bytes from 192.168.1.1: icmp_seq=37 ttl=64 time=0.909 ms
64 bytes from 192.168.1.1: icmp_seq=38 ttl=64 time=2.03 ms
64 bytes from 192.168.1.1: icmp_seq=39 ttl=64 time=0.839 ms
64 bytes from 192.168.1.1: icmp_seq=40 ttl=64 time=0.880 ms
9
27.01.2017, 12:36
5 ответов

Вот глупый способ сделать это, который действительно хорошо работает только с аутентификацией с открытым ключом:

Во-первых, убедитесь, что на вашем локальном компьютере есть nc на нем.

Во-вторых, все еще на вашем локальном компьютере, создайте сценарий (я назову его подключение к серверу ) и поместите его в место, известное вашему $ {PATH} about *:

#!/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 , то будет запущена команда , но (поскольку .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 , который не вызывает псевдопрокси.

3
27.01.2020, 20:06

Я бы выбрал:

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

, но если вы администратор, вы можете попробовать что-нибудь более чистое. Например, вы можете использовать опцию ssh SendEnv на стороне клиента для передачи определенной переменной, используйте AcceptEnv в конфигурации sshd (на стороне сервера), чтобы принять ее. , и на основе этого измените файл root .bashrc , чтобы настроить поведение в соответствии со значением переменной.

Это подразумевает изменение конфигурации sshd на всех хостах, а также их .bashrc . Не совсем "автономный" способ, однако ...

4
27.01.2020, 20:06

Если вы действительно хотите сделать это без изменений на стороне сервера, либо:

1) Запустите что-то вроде

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

Я не думаю, что в документации это слишком ясно, но -o опция упоминается и, похоже, работает.

2) Используйте expect:

Сценарий 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 ~$ 

Предполагается, что вы можете войти в систему без ввода паролей (для удаленного хоста или для ваших ключей ), иначе сценарий ожидания должен будет это учесть. Но с большим количеством машин у вас, скорее всего, это уже есть. Кроме того, я ожидал для знака доллара и пробела, отредактируйте это в соответствии с вашим запросом: «#» возможно.

Хотя если что-то напечатанное перед запросом содержит те же символы, вам нужно будет включить что-то более конкретное в ожидаемую строку.

Кроме того, этот сценарий не поддерживает передачу дополнительных аргументов ssh . Если вы собираетесь дать явную команду для запуска, вам, вероятно, не нужен vi-режим, но если вам нужно, скажем, туннелирование портов, это может быть проблемой.


Но в любом случае, я действительно думаю, что эту проблему следует решать в целевых системах с отдельными учетными записями ( sudo или просто старый добрый UID 0). Персонализированная конфигурация будет полезна и во многих других случаях, и, как правило, у вас будет множество файлов конфигурации и переменных среды, которые вы хотите установить. (Учтите, что администраторы могут не согласиться со значением $ EDITOR или содержимым virc или чем-то еще.)

Кроме того, удаление пользователей будет проще с отдельными учетными записями.

Любой способ синхронизации файлов на всех хостах также тривиально решит эту проблему, позволив вам войти в систему с помощью чего-то вроде ssh -t user @ host 'patricks_shell.sh' или ssh -t user @host 'bash --rcfile patrick.rc' .

3
27.01.2020, 20:06

вы можете создать собственный rc-файл, следуя этому руководству:

Пользовательский rc-файл | Secure Shell: The Definitive Guide

или введите действие командной строки в файл authorized_keys:

Конфигурация SSH автоматически выполнить удаленную команду | Обмен стеков Unix и Linux

1
27.01.2020, 20:06

Для простого решения на стороне клиента:

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

Это не удастся, если инициализация оболочки root скрипты явно используют set -o emacs или устанавливают РЕДАКТОР в emacs , или если файл root .initrc вызывает emacs ] привязки клавиш.

Остальная часть этого ответа касается серверных решений.


Это работает, когда вы ssh -ing в машину, а затем используйте 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 , чтобы выбрать rc-файл в качестве источника, либо напрямую, как с подходом $ SUDO_USER выше (в котором комментарий в $ ssh_comment может потребоваться некоторая очистка, если это путь), или с помощью оператора case , как в подходе $ SSH_CLIENT .

3
27.01.2020, 20:06

Теги

Похожие вопросы