Skip to main content

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 для задачи излишне гарно 😉