Предсказание 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

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 и вы используете группы или что-то, чтобы отслеживать всех ваших детей. Который вы нет.

  • SSH туннелирование через маршрутизатор busybox
  • Перенаправление трафика, поступающего из туннеля SSH в туннель VPN на устройстве Linux
  • Запуск X-клиентов через мульти-хост ssh-туннель
  • Как сделать ssh от школьного компьютера до домашнего компьютера?
  • Директива 'StrictModes' не допускается в блоке Match
  • Как настроить удаленный порт на порт 80 на мой локальный хост с помощью setcap?
  • ssh tunnel w / auth только для прокси
  • Я не могу успешно сгенерировать SSH-туннель внутри контейнера докеров
  • Как работает туннелирование SSH
  • Туннелирование через несколько компьютеров в Red Hat с различными пользователями и ключами
  • Почему wget не работает через туннель ssh? Что делает прокси-сервер для предотвращения использования ssh-client?
  • Interesting Posts

    Samba mount с приглашением пароля как пользователь без полномочий root

    Как получить текущий рабочий каталог перед его заменой

    Встречайте проблемы при попытке разместить ASP.NET Web Api на Debian с помощью Mono и Nginx

    Я отредактировал grub.cfg и linux mint теперь не будет загружаться (виртуальная коробка)

    Опрос для информации о последовательном порту

    Сортировка строки datetime в 12-часовом формате

    службы debian не работают

    Как я могу запустить сценарий рекурсивно в каталоге

    Не удается обойти экран входа с правильными учетными данными и никаких ошибок в Kali Linux

    Удалить заголовок в результатах журнала

    Почему у ] и ] есть другой синтаксис?

    Как выполнить двойную загрузку PC-BSD 10.3 (с файловой системой zfs) и debian 7 (crunchbang) с помощью загрузчика grub2 в MBR?

    Как перекодировать DVD в один файл?

    поиск каталогов, содержащих один файл, и отсутствие другого

    Возможно ли создать липкое перенаправление из stdout / stderr

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