@Kusalananda указал, что --login
запускает вызов профиля.bash _. В моем профиле.bash _была следующая строка
[[ -z $SSH_AGENT_PID && -z $DISPLAY ]] && exec -l ssh-agent $SHELL -c "bash --login"
Таким образом, каждый раз открывался второй баш.
У вас немного неправильный синтаксис для присваивания массивам, и ваш цикл не может работать так, как в bash
. На самом деле цикл, который вы написали, выглядит почти как то, что можно сделать в оболочке zsh
. Вы также забыли двойные кавычки ваших переменных.
Для решения zsh
:
#!/usr/bin/zsh
hosts=( host1 host2 host3 host4 ) # array of hosts
users=( user1 user2 user3 user4 ) # array of users
# loop over these and do the ssh thing
for user host in ${users:^hosts}; do
ssh $user@$host df -h
done
Подстановка параметра ${users:^hosts}
является специальной для оболочки zsh
и приведет к списку элементов из двух массивов users
и hosts
, чередующихся между ними. Для приведенного выше примера это сгенерирует список user1 host1 user2 host2 user3 host3 user4 host4
.
Цикл for
в zsh
может устанавливать несколько отдельных переменных, поэтому мы используем его для выбора пары имя пользователя -имя хоста в каждой итерации и вызываем ssh
.
Обратите внимание, что в оболочке zsh
не требуется заключать переменные в кавычки, так как оболочка не разделяет их на пробелы и не выполняет подстановку имён файлов по умолчанию.
A bash
решение:
#!/bin/bash
hosts=( host1 host2 host3 host4 ) # array of hosts
users=( user1 user2 user3 user4 ) # array of users
# set the positional parameters to the hosts
set -- "${hosts[@]}"
# Loop over the users.
# In each iteration, ssh to $1 for $user, then
# shift the next host into $1 when done.
for user in "${users[@]}"; do
ssh "$user@$1" df -h
shift
done
Это позволяет избежать необходимости иметь дело с индексами массива для объединения элементов двух массивов в пары. Он делает это, перебирая элементы одного из массивов и в то же время удаляя последовательные элементы другого, которые хранятся в списке позиционных параметров.
Предполагая, что на каждом хосте есть только один пользователь, вы можете поместить списки в массивы и циклически перебрать индексы одного из массивов (, не имеет значения, какой из них):
#!/bin/bash
Q_HOST=(host1 host2 host3) #array of hosts
Q_USER=(user1 user2 user3) #array of users
for i in ${!Q_HOST[@]}; do
host="${Q_HOST[i]}"
user="${Q_USER[i]}"
ssh "$user"@"$host" "df -h"
done
Вы также можете обратиться кparallel-ssh
(pssh
)для подобных задач.
#!/bin/bash
Q_HOST="host1 host2 host3"
#list of hosts.
Q_USER="user1 user2 user3"
#list of users
for host in Q_HOST; do
for user in Q_USER; do
echo "${user}@${host}"
ssh ${user}@${host} df -h
done
done