Все, что вам нужно сделать, это очистить файл и удалить все новые строки перед запятыми:
$ perl -0777pe 's/\n,/,/g' file
line0
line1
line2,line3
line4
line5,line6
line7,line8
line9
line10
line11
Предположим, что &&
— логический оператор. , а не означает «также запустить эту команду», это означает «выполнить эту команду, если другая успешно выполнена».
Это означает, что если команда rm
завершится ошибкой (, что произойдет, если какой-либо из трех каталогов не существует ), то mkdir
не будет выполнена. Это не похоже на поведение, которое вы хотите; если каталоги не существуют, вероятно, их можно создать.
Используйте;
Для разделения команд используется точка с запятой ;
. Команды выполняются последовательно, ожидая каждой, прежде чем перейти к следующей, но их успех или неудача не влияют друг на друга.
Экранирование внутренних кавычек
Кавычки внутри других кавычек должны быть экранированы, иначе вы создадите дополнительную конечную точку и начальную точку.Ваша команда:
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rm -rf Input Output Partition && mkdir -p EC2_WORKSPACE/$project Input Output Partition""
Становится:
ssh -n $username@$masterHostname "ssh -t -t $username@$line \"rm -rf Input Output Partition && mkdir -p EC2_WORKSPACE/$project Input OutputPartition\""
Ваша текущая команда из-за отсутствия экранированных кавычек должна выполняться:
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rm -rf Input Output Partition
если получится:
mkdir -p EC2_WORKSPACE/$project Input Output Partition"" # runs on your local machine
Вы заметите, что подсветка синтаксиса показывает здесь всю команду красным цветом, что означает, что вся команда представляет собой строку, передаваемую в ssh. Проверьте свою локальную машину; у вас могут быть каталогиInput
Output
и Partition
, где вы запускали это.
Вы можете поместить все ваши команды в отдельный скрипт на вашем "главном" сервере.
Основной сценарий
#!/bin/bash
rm -rf "Input Output Partition"
mkdir -p "EC2_WORKSPACE/$project Input Output Partition"
Затем в вашем ssh-скрипте назовите это так :SSH-скрипт
username="ubuntu"
masterHostname="myMaster"
while read line
do
ssh -n $username@$masterHostname "ssh -t -t $username@$line < /path/to/masterscript.sh"
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rsync --delete -avzh /EC2_NFS/$project/* EC2_WORKSPACE/$project""
done < slaves.txt
ИЛИ если все файлы должны быть на исходной машине, вы можете сделать что-то вроде этого:
сценарий1
script2="/path/to/script2"
username="ubuntu"
while read line; do
cat $script2 | ssh -t -t $username@line
done < slaves.txt
сценарий2
#!/bin/bash
rm -rf "Input Output Partition"
mkdir -p "EC2_WORKSPACE/$project Input Output Partition"
rsync --delete -avzh "/EC2_NFS/$project/* EC2_WORKSPACE/$project"
ssh-скрипт
script1="/path/to/script1"
username="ubuntu"
masterHostname="myMaster"
cat $script1 | ssh -n $username@$masterHostname
Некоторое время назад у меня была возможность использовать управляющие сокеты, как рекомендуют другие ответы (этот ответ, по сути, представляет собой комбинацию использования управляющих сокетов, таких как этот ответ и скриптов, таких как этот ответ ).
Примером использования был взлом :Файл authorized_keys
целевого пользователя периодически перезаписывался запланированным заданием, и я хотел быстро протестировать вещи, не проходя через красную -ленту, необходимую для добавления чего-то в этот файл. Поэтому я бы настроил цикл while, который добавлял ключ в этот файл по мере необходимости, запускал мой тест и отменял цикл. Однако было бы небольшое окно, в котором запланированная задача перезаписала бы файл, и мой цикл все еще продолжал бы sleep
. Так,установка управляющего сокета в начале позволила бы моему сценарию SSH без проблем работать позже:
#! /bin/bash -xe
. "${CONFIG_DIR}/scripts/setup-ssh.sh"
# Build and test
export TEST_LABEL="${_started_by}-${BUILD_TAG%-BUILD*}"
#...
xargs --arg-file test-list \
--no-run-if-empty \
--process-slot-var=NUM \
--max-procs=${#SERVERS[@]} \
--max-args="${BATCH_SIZE:-20}" \
"${CONFIG_DIR}/scripts/run-test.sh"
Где setup-ssh.sh
это:
export SSH_CONFIG="${CONFIG_DIR}/scripts/.ssh-config"
mapfile -t SERVERS < "${CONFIG_DIR}/scripts/hosts"
for SERVER in "${SERVERS[@]}"
do
while ! ssh -F "${SSH_CONFIG}" "${SERVER}" -fnN; do sleep 1; done
scp -F "${SSH_CONFIG}" "${CONFIG_DIR}/scripts/ssh-script.sh" "${SERVER}":"${TEST_LABEL}.sh"
done
И.ssh-config
:
Host test-*
User test
StrictHostKeyChecking no
ControlMaster auto
ControlPath /tmp/ssh-%h-%p-%r
Иrun-test.sh
:
mapfile -t TEST_SERVERS < "${CONFIG_DIR}/scripts/hosts"
ssh -F "${SSH_CONFIG}" "${TEST_SERVERS[$NUM]}" "./${TEST_LABEL}.sh"
Последовательность выглядит следующим образом:
setup-ssh.sh
. setup-ssh.sh
busy -зацикливает серверы до тех пор, пока на всех них не будет настроен контрольный сокет. Файл hosts
просто перечисляет имена хостов серверов по одному в строке. ${CONFIG_DIR}/scripts/.ssh-config
, пока я не укажу этот файл с помощью -F
, соединения SSH не будут его использовать. Таким образом, это позволяет мне использовать управляющий сокет только там, где он мне нужен, используя опцию F
. xargs
для распределения рабочей нагрузки по серверам, запуская новые задания, как только заканчиваются запущенные. Вы всегда можете указать в своем переходнике Мультиплексирование в OpenSSH
Multiplexing is the ability to send more than one signal over a single line or connection. With multiplexing, OpenSSH can re-use an existing TCP connection for multiple concurrent SSH sessions rather than creating a new one each time.
An advantage with SSH multiplexing is that the overhead of creating new TCP connections is eliminated. The overall number of connections that a machine may accept is a finite resource and the limit is more noticeable on some machines than on others, and varies greatly depending on both load and usage. There is also significant delay when opening a new connection. Activities that repeatedly open new connections can be significantly sped up using multiplexing.
Для этого в/etc/ssh/ssh_config
:
ControlMaster auto
ControlPath ~/.ssh/controlmasters/ssh_mux_%h_%p_%r
ControlPersist 30m
Таким образом, любые последовательные подключения к одному и тому же серверу в течение следующих 30 минут будут выполняться повторно с использованием предыдущего подключения ssh.
Вы также можете определить его для машины или группы машин. Взято по предоставленной ссылке.
Host machine1
HostName machine1.example.org
ControlPath ~/.ssh/controlmasters/%r@%h:%p
ControlMaster auto
ControlPersist 10m