Есть несколько вариантов как выполнить несколько команд на удаленном сервере по 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




