Предсказание PID ранее начатой ​​команды SSH

Это самое странное.

В сценарии я запускаю туннель SSH следующим образом:

ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar 

Это запускает экземпляр ssh который переходит в фоновый режим, и выполнение сценария продолжается. Затем я сохраняю его PID (для его убийства позже), используя bash $! переменная . Чтобы это сработало, я добавляю & к команде ssh даже если он уже идет в фоновом режиме сам по себе (иначе $! Не содержит ничего). Таким образом, например, следующий скрипт:

 #!/bin/bash ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar & echo $! pgrep -f "ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar" 

выходы

 (some ssh output) 28062 28062 

… два раза тот же PID, как и ожидалось. Но теперь, когда я выполняю эту точную последовательность команд с терминала, вывод PID через $! (в том смысле, что это не PID экземпляра ssh ). От терминала:

 $ ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar & [1] 28178 (some ssh output) $ echo $! 28178 $ pgrep -f "ssh -o StrictHostkeyChecking=no -fND 8080 foo@bar" 28181 

Это не всегда 3 номера. Я также заметил разницу в 1 или 2. Но это никогда не тот же PID, как я и ожидал, и, как и в случае, когда эта последовательность команд запускается внутри скрипта.

  1. Может кто-нибудь объяснить, почему это происходит? Я думал, что это может быть связано с тем, что начальный вызов ssh фактически вызывает другой процесс, но почему он работает из сценария?

  2. Это также заставило меня сомневаться в том, что использование $! в моем скрипте, чтобы получить ssh PID, как описано выше, действительно будет работать (хотя он до сих пор). Действительно ли это действительно? Я чувствовал, что это «чище», чем использование pgrep

  • автоматическое восстановление SSH-соединения при загрузке
  • SSH через штопор к удаленному серверу не работает
  • Приложение Directx с использованием вина поверх ssh -x
  • X Window открывается с экрана
  • Могу ли я использовать SSH для туннелирования определенного порта через мой сервер
  • двуличие с туннелированием ssh
  • Запустить скрипт после входа GDM в GNOME?
  • Отключить SSH-туннель с KVM VNC-сервером
  • One Solution collect form web for “Предсказание PID ранее начатой ​​команды SSH”

    Оболочка $! переменная знает только pid процесса, запускаемого оболочкой. Как вы подозревали, вызов ssh с использованием -f запускает собственный процесс, поэтому он может перейти в фоновый режим, поэтому общее дерево процессов выглядит как [1]:

     shell | +--ssh<1> (pid is $!) | +--ssh<2> (pid is different) 

    ssh<1> выходит очень скоро после вызова; поэтому значение в $! вряд ли будет полезна. Это ssh<2> который осуществляет удаленную связь и выполняет ваше туннелирование для вас, и единственный способ надежно получить его PID – это изучить таблицу процессов, как вы это делаете с pgrep [2]. Метод pgrep вероятно, будет правильным здесь.

    Что касается того, почему он работает в скрипте, но не в интерактивном режиме, это, вероятно, состояние гонки. Поскольку вы помещаете первый ssh в фоновом режиме, shell и ssh выполняются одновременно, а ssh выполняет некоторую умеренную криптографическую аутентификацию с процессором и некоторые сетевые обратные вызовы. Вероятно, что pgrep вы запускаете в скрипте, просто запускается до того, как ssh<1> перейдет в фоновый режим. Чтобы обойти это, позже запустите pgrep либо вызовом sleep , либо просто позвонив только тогда, когда вам действительно понадобится PID.

    [1]: Технически, это может быть сложнее, чем это, если ssh использует классическую двойную fork для фона. В этом случае между ними будет еще один эфемерный ssh процесс.

    [2]: Если вы не systemd и вы используете группы или что-то, чтобы отслеживать всех ваших детей. Который вы нет.

    Interesting Posts

    Как я могу заставить эту команду java действовать в каждом файле, найденном командой find?

    Как заставить «yum search» использовать локальные метаданные / кеш?

    Как мне различать выходы двух команд?

    Procmail – автоматический ответ с приложением

    Доступны ли какие-либо расширенные регистрации для заданий cron?

    Служба Squid systemd не запускается при загрузке

    Может ли исходный каталог eCryptfs удаленно удален

    Гость виртуальной коробки в другой подсети, чем хост

    установить ограничение скорости передачи пакетов через iptables

    Curl or Lynx: возможно ли снятие Javascript?

    Как ограничить количество сообщений, отправленных через почтовый сервер?

    apache2: Не удалось открыть файл конфигурации /etc/apache2/apache2.conf: Ошибка ввода / вывода

    Как получить доступ к камере безопасности и скрывать ее в / dev / video?

    Почему существуют три синтаксиса для установки переменных в сценариях оболочки?

    Команда resize2fs не найдена

    Linux и Unix - лучшая ОС в мире.