ssh scripting, или как избежать головной боли с кавчычками, скобками и прочими квотами ;)
Баянище, конечно, но я не одинок в изобретении велосипедов, и склонен постоянно терять скрипты в неизвестном закоулке, потому сохраню здесь 😉
Задача простая: выполнить условно сложный скрипт на удаленной машине. Проблема – в общем-то, все кавычки нужно экранировать, проверять и еще раз экранировать, что вымораживает при мало-мальски большом объёме “писательства”. Простой пример:
ls -1 /dev/rdsk/c0*d0s2 | while read di ; do echo -en "${di}:\t" && smartctl -a $di | egrep ^194 | awk '{print $10}' ; done
и попытка впихнуть его в echo | ssh даст нам очевидный болт. Соотв., либо нам нужно этот скрипт предварительно разместить на целевой машине и исполнить его, либо же применить небольшой, так сказать, воркэраунд, “перегнав” его в base64 заранее, но по месту.
#!/bin/bash
# cmd:
#ls -1 /dev/rdsk/c0*d0s2 | while read di ; do echo -en "${di}:\t" && smartctl -a $di | egrep ^194 | awk '{print $10}' ; done
# base64 -w0:
#bHMgLTEgL2Rldi9yZHNrL2MwKmQwczIgfCB3aGlsZSByZWFkIGRpIDsgZG8gZWNobyAtZW4gIiR7ZGl9Olx0IiAmJiBzbWFydGN0bCAtYSAkZGkgfCBlZ3JlcCBeMTk0IHwgYXdrICd7cHJpbnQgJDEwfScgOyBkb25lCg==
RCMD="bHMgLTEgL2Rldi9yZHNrL2MwKmQwczIgfCB3aGlsZSByZWFkIGRpIDsgZG8gZWNobyAtZW4gIiR7ZGl9Olx0IiAmJiBzbWFydGN0bCAtYSAkZGkgfCBlZ3JlcCBeMTk0IHwgYXdrICd7cHJpbnQgJDEwfScgOyBkb25lCg=="
ssh snooky "echo $RCMD | base64 -d | sudo bash"
Ну или же делаем совсем слабочитаемый (ладно, нечитаемый) однострочник:
ssh snooky "echo bHMgLTEgL2Rldi9yZHNrL2MwKmQwczIgfCB3aGlsZSByZWFkIGRpIDsgZG8gZWNobyAtZW4gIiR7ZGl9Olx0IiAmJiBzbWFydGN0bCAtYSAkZGkgfCBlZ3JlcCBeMTk0IHwgYXdrICd7cHJpbnQgJDEwfScgOyBkb25lCg== | base64 -d | sudo bash"
Не особо элегантный выход, но используя base64 – я категорически избавляю себя от всевозможной головной боли. Особенно это становится актуально, когда мне нужно выполнить нечто на десятке-другом машин, а разнообразные ansible для задачи излишне гарно 😉