Есть несколько вариантов как выполнить несколько команд на удаленном сервере по SSH.
Первый – используя разделитель “;
“:
$ ssh -p 2222 [email protected] ls /opt/; ls -1 /var [email protected]'s password: mailstat pflogsumm-1.1.1 pflogsumm-1.1.1.tar.gz Keychains ...
Второй – используя одинарные кавычки:
$ ssh -p 2222 [email protected] ' > ls -l /opt > ls -l /var > ' [email protected]'s password: total 52 drwxr-xr-x 2 root root 4096 Aug 22 2014 mailstat drwxr-xr-- 2 root root 4096 Jul 12 2014 pflogsumm-1.1.1 -rw-r--r-- 1 root root 44627 Apr 6 2007 pflogsumm-1.1.1.tar.gz total 72 drwxr-xr-x. 10 root root 4096 Dec 25 15:56 cache ... drwxr-xr-x 10 root root 4096 Dec 15 17:51 www drwxr-xr-x. 2 root root 4096 Sep 23 2011 yp
Но в таком случае не будут раскрыты переданные переменные:
$ var="VALUE" $ ssh -p 2222 [email protected] ' > echo $HOME > echo $var > ' [email protected]'s password: /home/user
Локальная переменная на удаленном сервере $HOME
работает, а вот значение переданной переменной – нет.
Добавляем bash -c
и двойные кавычки:
$ var="VALUE" $ ssh -p 2222 [email protected] "bash -c ' > echo $HOME > echo $var > '" [email protected]'s password: /Users/local.user VALUE
Обратите внимание на значение $HOME - /Users/local.user
.
Следующий способ – перенаправить список команд из файла:
$ cat bashlines var="VALUE" ls -l /opt echo $HOME echo $var
$ ssh -p 2222 [email protected] < bashlines Pseudo-terminal will not be allocated because stdin is not a terminal. [email protected]'s password: total 52 drwxr-xr-x 2 root root 4096 Aug 22 2014 mailstat drwxr-xr-- 2 root root 4096 Jul 12 2014 pflogsumm-1.1.1 -rw-r--r-- 1 root root 44627 Apr 6 2007 pflogsumm-1.1.1.tar.gz /home/setevoy VALUE
Или – используя heredoc
:
$ ssh -p 2222 [email protected] <<EOF > var="VALUE" > ls -l /opt > echo $HOME > echo $var > EOF Pseudo-terminal will not be allocated because stdin is not a terminal. [email protected]'s password: total 52 drwxr-xr-x 2 root root 4096 Aug 22 2014 mailstat drwxr-xr-- 2 root root 4096 Jul 12 2014 pflogsumm-1.1.1 -rw-r--r-- 1 root root 44627 Apr 6 2007 pflogsumm-1.1.1.tar.gz /Users/local.user VALUE
Что бы избежать ошибки:
“Pseudo-terminal will not be allocated because stdin is not a terminal.”
используйте опцию -T
:
$ man ssh | grep "-T" -T Disable pseudo-tty allocation. warded to host on port over the secure channel. Implies -N, -T,
Например:
$ ssh -T -p 2222 [email protected] < bashlines [email protected]'s password: total 52 drwxr-xr-x 2 root root 4096 Aug 22 2014 mailstat drwxr-xr-- 2 root root 4096 Jul 12 2014 pflogsumm-1.1.1 -rw-r--r-- 1 root root 44627 Apr 6 2007 pflogsumm-1.1.1.tar.gz /home/setevoy VALUE
И пример bash
-скрипта деплоя (точнее – дестроя перед деплоем 🙂 ), в котором используются многострочные команды SSH:
#!/usr/bin/env bash RSA_KEYS=".ssh/id_rsa" USER="knife" HOST="$1" JBOSS_HOME="/opt" JBOSS_WORK_DIR="jboss" JBOSS_DEPLOY_DIR_NAME="jboss-eap-6.3" JBOSS_DEPLOY_ARCH_NAME="$JBOSS_DEPLOY_DIR_NAME.zip" me="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" echo -e "n[$me] JBoss destroy started.n" echo -e "Root directory: $JBOSS_HOME" echo -e "JBoss home: $JBOSS_WORK_DIR" echo -e "JBoss temp dir: $JBOSS_DEPLOY_DIR_NAME" echo -e "JBoss deploy archive: $JBOSS_DEPLOY_ARCH_NAMEn" if [ -z "$HOST" ]; then echo -e "ERROR: HOST must be defined with first argument! Exit.n" exit 1 fi if [ -e "$RSA_KEYS" ]; then chmod 600 "$RSA_KEYS" else echo -e "ERROR: No private RSA key found! Exit.n" exit 1 fi echo -e "Worknig on $HOST under user $USER.n" rm_work_dir () { ssh -t -t -oStrictHostKeyChecking=no -i "$RSA_KEYS" "$USER@$HOST" "bash -c ' if [ -d "$JBOSS_HOME/$JBOSS_WORK_DIR" ]; then echo -e "Removing $JBOSS_HOME/$JBOSS_WORK_DIR:" sudo rm -rfv "$JBOSS_HOME/$JBOSS_WORK_DIR" else echo -e "$JBOSS_HOME/$JBOSS_WORK_DIR not found, skipping..." fi '" } rm_deploy_dir () { ssh -t -t -oStrictHostKeyChecking=no -i "$RSA_KEYS" "$USER@$HOST" "bash -c ' if [ -d "$JBOSS_HOME/$JBOSS_DEPLOY_DIR_NAME" ]; then echo -e "Removing $JBOSS_HOME/$JBOSS_DEPLOY_DIR_NAME:" sudo rm -rfv "$JBOSS_HOME/$JBOSS_DEPLOY_DIR_NAME" else echo -e "$JBOSS_HOME/$JBOSS_DEPLOY_DIR_NAME not found, skipping..." fi '" } rm_deploy_arch () { ssh -t -t -oStrictHostKeyChecking=no -i "$RSA_KEYS" "$USER@$HOST" "bash -c ' if [ -e "$JBOSS_HOME/$JBOSS_DEPLOY_ARCH_NAME" ]; then echo -e "Removing $JBOSS_HOME/$JBOSS_DEPLOY_ARCH_NAME:" sudo rm -fv "$JBOSS_HOME/$JBOSS_DEPLOY_ARCH_NAME" else echo -e "$JBOSS_HOME/$JBOSS_DEPLOY_ARCH_NAME not found, skipping..." fi '" } if rm_work_dir; then echo -e "n[$me] Work dir cleaned.n" fi if rm_deploy_dir; then echo -e "n[$me] Deploy directory cleaned.n" fi if rm_deploy_arch; then echo -e "n[$me] Deploy archive cleaned." fi echo -e "n[$me] JBoss destroy completed successfully.n" exit 0