Расширение переменной и экранирование в синтаксисе heredoc

1136
Brando__

У меня есть следующий скрипт для очистки таблицы arp коммутатора. Независимо от того, как я пытаюсь избежать всего, процитирую это или иначе пытаюсь, я не могу заставить это работать должным образом. Строка bash интерпретируется моей собственной оболочкой перед передачей в интерпретатор Expect. Я хочу, чтобы строка bash передавалась буквально, как и для переключателя, который должен быть там выполнен, НО мне нужно каким-то образом увеличить переменную $ thirdoctet в какой-то момент, и я хочу, чтобы ssh @ был расширен.

Кажется, Аристе не нравится устанавливать переменные. Я не смог определить третий октет = 3 внутри.

function get-arp { echo $  /usr/bin/expect > arista-arp-dump-$ << EOF spawn ssh admin@$ expect "assword: " send "password\r" expect "localhost>"  send "bash for i in `seq 1 5`; do ping -c 1 10.$thirdoctet.1.$i; done" expect "localhost>" send "bash for i in `seq 10 19`; do ping -c 1 10.$thirdoctet.1.$i; done" expect "localhost>" send "show ip arp\r" expect "localhost>" send "exit\r" expect "eof" EOF  tail -n +2 arista-arp-dump-$ | grep b8ae | awk '' | tr ' ' ',' > arista-arp.csv  sed 's/\(.*\)\./\1 /' arista-arp.csv > tmp && mv tmp arista-arp.csv   sed 's/\(.*\)\./\1 /' arista-arp.csv > tmp && mv tmp arista-arp.csv  sed '/^$/d;s/[[:blank:]]//g' arista-arp.csv > tmp && mv tmp arista-arp.csv  rm arista-arp-dump-$  }  get-arp 
0
Я попытался исправить форматирование вашего вопроса; пожалуйста, проверьте его и при необходимости исправьте. (Кроме того, я избавился от UUOC, потому что UUOC; замените его обратно, если это вызывает сильную изжогу.) Что вы пытались определить третьим актом? А что с `send 'bash для i in ...`? Вы когда-нибудь работали над этим? Попробуйте скрипт, который делает это и ничего больше. G-Man 7 лет назад 0
Это никогда не работает в сценарии. Выполнение этой команды bash непосредственно в интерфейсе командной строки arista работает как задумано. Brando__ 7 лет назад 0
Буквально набрав `bash` (пробел)` for` (пробел) `i` ...? G-Man 7 лет назад 0
localhost # bash для i в `seq 1 5`; do ping -c 1 10.199.1. $ i; выполнено PING 10.199.1.1 (10.199.1.1) 56 (84) байт данных. 64 байта из 10.199.1.1: icmp_req = 1 ttl = 64 время = 2,03 мс --- статистика пинга 10.199.1.1 --- 1 передано пакетов, 1 получено, 0% потерь пакетов, время 0 мс rtt мин / avg / max / mdev = 2,032 / 2,032 / 2,032 / 0,000 мс PING 10.199.1.2 (10.199.1.2) 56 (84) байтов данных. 64 байта из 10.199.1.2: icmp_req = 1 ttl = 64 время = 2,76 мс .... localhost Да, работает. Brando__ 7 лет назад 0
(1) Хорошо, я немного удивлен, но я поверю на ваше слово. (2) Подсказка: не размещайте в комментариях сообщения, которые должны состоять из нескольких строк. Не публикуйте в комментариях вещи, содержащие `\` `, пока не знаете, как это сделать. (3) Возможно, у вас проблема с `$` (но вы уже знали об этом, не так ли?) Можете ли вы сделать что-то простое, например `bash for i in 1 2 3 4 5 6 7 8; делать эхо буйвола; сделано `через 'ожидать`? G-Man 7 лет назад 0

1 ответ на вопрос

0
glenn jackman

Проблема в том, что у вас есть переменные, которые вы ожидаете заменить в разное время (даже на разных серверах), но вы закодировали скрипт так, чтобы все они заменялись один раз, когда запускается функция bash. Баш Heredoc действует как двойные кавычки строки, так что все переменные $ip, $thirdoctetи $iзаменяется перед текстом Heredoc передается команде ожидать. Кажется, что вы хотите $ipи $thirdoctetдолжны быть расширены, но нет $i. Вы должны быть немного умнее, когда цитируете.

Я бы сделал это:

  1. одиночный кавычка heredoc, так что никакие переменные не заменяются оболочкой
  2. экспортировать $ipи $thirdoctetпеременные поэтому ожидать доступа к ним.
  3. экранируйте $iпеременную, чтобы она заменялась только bash на удаленной машине
  4. Вы забыли «нажать Enter» - отсутствует \rв паре команд отправки
function get-arp { export ip export thirdoctet  # note the quotes: ........................v...v /usr/bin/expect > arista-arp-dump-$ << 'EOF' # use the 'ip' variable from the environment spawn ssh admin@$env(ip) expect "assword: " send "password\r" expect "localhost>"   # use the 'thirdoctet' variable from the environment and escape `\$i` send "bash for i in `seq 1 5`; do ping -c 1 10.$env(thirdoctet).1.\$i; done\r" expect "localhost>" send "bash for i in `seq 10 19`; do ping -c 1 10.$env(thirdoctet).1.\$i; done\r" expect "localhost>"  send "show ip arp\r" expect "localhost>" send "exit\r" expect "eof" EOF ...