Передать переменные из интерактивного сеанса из сценария bash

Здравствуйте, люди мира,

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

Нашими приложениями управляет Pacemaker, и я подумал, что смогу написать функцию, которая будет принимать необходимые переменные и действовать. Остановитесь на одном сайте, начните на другом. После того, как я перешел к удаленному компьютеру с помощью ssh, я не могу вернуть значение команды grep/awk для статуса приложения в PCS.

Я столкнулся с несколькими проблемами и пробовал ответы на stackoverflow и других сайтах.

  1. Я отправляю команду ssh в /dev/null 2>&1, когда на экране появляются баннеры, которые администратор unix имеет для локального пользователя, и -q не имеет с этим дело. Это останавливает возврат чего-либо?
  2. при использовании awk '{print \\\\\\$4}' в коде я получаю ошибку "обратная косая черта не последний символ в строке"
  3. Чтобы обойти это, я попытался result=$(sudo pcs status | grep nds_$resource), однако это привело к ошибке пароля на sudo
  4. Я пробовал >/dev/tty and >$(tty)
  5. Я попытался не подавлять ssh (удалить /dev/null 2>&1) и поместить вывод в переменную при вызове функции, удалив awk из записи sudo pcs status.
result=$(pcs_call "$site1" "1" "2" "disable" "pmr")
echo $result | grep systemd 

Это было нормально, но когда я добавил | awk '{print \\\$4}', я получил четвертое слово в баннере.

Любая помощь будет оценена по достоинству, так как я занимаюсь этим уже несколько дней.

Я смотрел этот ответ от Бруно, но не знаю, как реализовать, поскольку у меня есть несколько sudo команд.

Ниже приведен мой код функции для тестирования на одной машине;

site1=lon
site2=ire


function pcs_call()
{
 site=$1
 serverA=$2
 serverB=$3
 activity=$4
 resource=$5

ssh -tt ${site}servername0${serverA}  <<SSH > /dev/null 2>&1
         sudo pcs resource ${activity} proc_${resource}
         sleep 10
         sudo pcs status  | grep proc_$resource | awk '{print \\\$4}' | tee $output
         exit
SSH
echo $output
}

echo ====================================================================================
echo Shutting Down PMR in $site1
pcs_call "$site1" "1" "2" "disable" "pmr"

Почему в команде $4 перед awk используются символы обратной косой черты?

Daweo 08.02.2023 16:26
idownvotedbecau.se/noresearch
Paul Hodges 08.02.2023 16:55

3 обратных слэша таковы, что awk захватит четвертый символ. Если я их не использую, то будет использоваться четвертая переменная, переданная из начальной функции, например, awk '{print disabled}'

Red_badger 08.02.2023 17:00
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я бы посоветовал начать с вставки всего этого в ShellCheck.net и исправления ошибок до тех пор, пока не останется предложений, но здесь есть некоторые серьезные проблемы, с которыми shellcheck не сможет справиться в одиночку.

  1. > /dev/null говорит: «Выбрасывайте в битбакет все возвращаемые данные. 2>&1 говорит: «Отправляйте любые полезные отчеты об ошибках на stderr, куда бы ни направлялся stdout». Ваш первоначальный оператор, предназначенный для извлечения информации из удаленной системы, немедленно отбрасывает ее. Если вы не просто хотите, чтобы в удаленной системе произошло что-то, о чем вы не хотите знать больше локально, вы тратите свое время на что-либо после этого, потому что вы сбросили все, что он должен был сказать.
  2. Вам нужна только одна обратная косая черта в этом выражении awk, чтобы процитировать знак доллара на $4.
  3. Если у вас нет пароля sudo в удаленной системе, это не сработает для вас. Я думаю, нам нужно больше информации об этом, прежде чем мы обсудим это глубже.
  4. Пока вызов ssh передает все в /dev/null, ничто внутри передаваемого блока кода не даст вам никаких результатов в вызывающей системе.
  5. В вашем коде вы используете $output, но похоже, что вы намереваетесь установить tee? Так не бывает . Аргумент tee — это имя файла, в который он ожидает записать копию данных, которые также передаются на стандартный вывод (т.е. как в «Т»-соединении, в сантехнике), но НЕ присваивает переменные.

(Кроме того, вы еще даже не используете serverB, но вы можете добавить его обратно, когда преодолеете текущие проблемы.)

В конце вы echo $output, который, вероятно, пуст, так что в основном это просто echo, который не будет отправлять ничего, кроме новой строки, которая будет просто отправлена ​​обратно на исходный сервер и сброшена в /dev/null, так что все это бессмысленно... .

Давайте убирать

sudo pcs status | grep proc_$resource | awk '{print \\\$4}' | tee $output

а попробуй немного по другому, да?

Во-первых, я предполагаю, что у вас нет пароля sudo, в противном случае будет совершенно другой разговор, чтобы решить это.

Во-вторых, как правило, использование в конвейере как grep, так и awk является антипаттерном, так как они оба по своей сути являются механизмами регулярных выражений. Выбери один. Если вы можете заставить grep делать то, что хотите, это довольно эффективно. Если нет, awk очень гибкий. Пожалуйста, прочтите страницы документации по используемым вами инструментам, если что-то не работает. Быстрый поиск «bash man grep» или «awk manual» быстро даст вам отличные ресурсы, и они вам понадобятся, если вы пытаетесь сделать что-то настолько сложное.

Итак, давайте посмотрим на переделку, сделав некоторые предположения...

function pcs_call() {
  local site = "$1" serverA = "$2" activity = "$3" resource = "$4" # make local and quotes habits you only break on purpose
  ssh -qt ${site}servername0${serverA} "
    sudo pcs resource ${activity} proc_${resource}; sleep 10; sudo pcs status; 
  " 2>&1 | awk -v resource = "$resource" '$0~"proc_"resource { print $4 }'
}

pcs_call "$site1" 1 disable pmr # should print the desired field

Если вы хотите записать данные в переменную для последующего использования -

var1 = "$( pcs_call "$site1" 1 disable pmr )"

дополнение

Отвечая на ваш вопрос, используйте $(seq 1 10) или просто {1..10}.

ssh -qt chis03 '
    for i in {1..10}; do sudo pcs resource disable ipa $i; done;
    sleep 10; sudo pcs status;
' 2>&1 | awk -v resource=ipa '$0~"proc_"resource { print $2" "$4 }'

Сначала он сообщает о awk, потому что порядок элементов в конвейере «не определен», но стандартный вывод ssh подключен к стандартному выводу awk (и, поскольку он был заменен на стандартный вывод, то же самое относится и к стандартному выводу), поэтому они работает асинхронно/одновременно.

Да, поскольку они используют литералы, одинарные кавычки проще и эффективнее «лучше». Если абстрагироваться с помощью vars, это не сильно изменится, но переключитесь обратно на двойные кавычки.

# assuming my vars (svr, verb, target) preset in the context
ssh -qt $svr "
    for i in {1..10}; do sudo pcs resource $verb $target \$i; done;
    sleep 10; sudo pcs status;
" 2>&1 | awk -v resource = "$target" '$0~"proc_"resource { print $2" "$4 }'

Это помогает?

Привет Павел, Спасибо, что нашли время, чтобы прочитать это.

Red_badger 08.02.2023 17:52

Решение сработало 1) Да, я думал, что /dev/null подавит ВСЕ выходные данные, однако я видел текст из удаленной оболочки. Это потому, что я использовал EOF (SSH в моем сценарии), поэтому мне нужно было иметь \\\$ 4 в awk. 2) Спасибо за информацию о тройнике, я бы увидел, что я создавал файлы в папке, из которой я запускал скрипт, с выводом скрипта. 3) спасибо за совет по grep/awk - именно так я использовал эту команду в течение многих лет, я постараюсь улучшить свой awk. 4) да sudo был без пароля 5) serverB в другой части скрипта не выложил.

Red_badger 08.02.2023 18:03

Привет, Пол. Разрешает ли этот метод, в отличие от heredoc, эту команду; ``` для i в seq 1 10; отключить ресурс sudo pcs ipa \$i; сделанный; спать 10; статус sudo ПК; " 2>&1 | awk -v resource=ipa '$0~"proc_"resource { print $2" "$4 }' ``` Это не позволяет мне запускать его, у меня есть несколько приложений, работающих на одном сервере

Red_badger 09.02.2023 13:22

Команда awk выполняется перед циклом for. ++ awk -v resource=ipa '$0~"pcs_"resource { print $2" "$4 }' +++ seq 1 10 ++ ssh -qt chis03 ' '\''for i in 1 2 3 4 5 6 7 8 9 10; отключите ресурс sudo pcs ipa_; сделанный; спать 10; статус sudo pcs;'\'' '

Red_badger 09.02.2023 15:24

Решение: используйте одинарные кавычки вместо двойных. это потому, что я не передаю внешнюю переменную, поэтому мне не нужно ее сохранять, просто нужно использовать внутреннюю переменную для команды. ssh -qt ${site}server${serverA} 'для i в $(seq 1 10); отключите ресурс sudo pcs ipa_$i; сделанный; спать 10; статус sudo ПК; ' 2>&1 | awk -v resource=ipa '$0~"pcr_"resource {print $2" "$4}"

Red_badger 09.02.2023 18:14

Между прочим, нет ничего плохого в использовании вот этого документа. Мне просто нравятся простые кавычки, но если вам нужны как одинарные, так и двойные кавычки в вашем коде, here-doc — хороший способ разрешить и то, и другое! Хорошо добавлять инструменты в набор инструментов, если вы понимаете их и эффективно используете. Строка здесь — еще одна, которую я часто использую, но опять же, здесь она не нужна.

Paul Hodges 09.02.2023 18:39

Другие вопросы по теме