Лучше всего использовать printf
. У вас есть две строки, и вы хотите вывести их с дополнительным форматированием. Это именно то, что делает printf
.
$ printf "%s @@ %s\n" "$(cat /proc/loadavg)" "$(date)"
Ваша попытка tr
не работает, поскольку tr
изменяет символов , а не слова. Вы можете использовать его для замены символов новой строки одним единственным символом:
$ ( cat /proc/loadavg; date ) | tr '\n' '@'
... но это не совсем то, что вам нужно.
Ваша попытка sed
не работает, так как новая строка удаляется из ввода sed
(т.е. sed -n '/ \ n / p' inputfile
никогда бы ничего не напечатал).
Вы все еще можете сделать это с помощью sed
, если вы прочитаете вторую строку (с даты
) с помощью команды редактирования N
при редактировании первой строки (которая помещает между ними новую строку):
$ ( cat /proc/loadavg; date ) | sed 'N;s/\n/ @@ /'
... но я лично предпочел бы решение printf
.
Если я правильно понимаю, вы хотите установить SSH-соединение между A и B, скажем, от A до B. Можно установить TCP-соединение от A до B (B не находится за брандмауэром, который делает это невозможным), но вас беспокоит, что разрешить пользователю от A до входа в B может привести к нарушению безопасности на B, если A не заслуживает доверия.
OpenSSH предоставляет простое решение для этого. В ~ / .ssh / authorized_keys
вы можете ограничить действие ключа для выполнения только одной команды. Создайте новую пару ключей на A:
serverA$ ssh-keygen -N '' -f ~/.ssh/copy_to_B.id_rsa
serverA$ cat ~/.ssh/copy_to_B.id_rsa.pub
Возьмите сгенерированный открытый ключ и добавьте принудительную команду в конце строки. Также добавьте параметр restrict
, чтобы предотвратить такие вещи, как переадресация портов (которая может, например, позволить A делать запросы, поступающие изнутри периметра брандмауэра B). Новая строка в ~ / .ssh / authorized_keys
на B будет выглядеть так:
ssh-rsa AAAA… luc@serverA restrict command="cat >~/backups/B/latest.tgz"
Теперь при использовании этого ключа для входа в B команда cat> ~ / backups / B /latest.tgz
будет выполняться независимо от того, что вы передаете в ssh
. Таким образом, все, что B может сделать, это записать в файл
serverA$ tar … | ssh -i ~/.ssh/copy_to_B.id_rsa luc@serverB whatever
. Если SSH-сервер на B недостаточно новый, у него может не быть restrict
. Если у него нет ограничения
, используйте вместо него no-port-forwarding
плюс все остальные доступные параметры no-…
(проверьте ] man sshd
на B).
Вы можете ссылаться на исходную команду в принудительной команде через переменную SSH_ORIGINAL_COMMAND
, но будьте осторожны, если вы сделаете здесь что-то сложное, будет сложно гарантировать, что вы не открываете дыру в безопасности. Вот простая оболочка, которая позволяет B записывать в любой файл в ~ / backups / B
, передавая желаемое имя файла в качестве команды - обратите внимание, что оболочка заносит символы в белый список, чтобы избежать таких вещей, как запись в ../../.ssh/authorized_keys
.
ssh-rsa AAAA… luc@serverA restrict command="case $SSH_ORIGINAL_COMMAND in *[!-.A-Za-z0-9_]*) echo >&2 'bad target file'; exit 120;; [!-.]*) cat >~/backups/B/\"$SSH_ORIGINAL_COMMAND\";; *) echo >&2 'bad target file'; exit 120;; esac"
Если A
может использовать ssh для B
и при условии, что у вас запущен агент ssh
:
ssh -A A '
cd /src && tar cf - . | gzip -1 | ssh B "
cd /dst && gunzip | tar xpf -"'
Обратите внимание, что с -A
, мы предоставляем удаленному пользователю на A
доступ к вашему ssh-агенту. Возможно, вы не захотите этого делать, если не доверяете администраторам этого сервера или кому-либо, кто может иметь доступ к этой учетной записи удаленного пользователя. Они не смогут получить ваши ключи ssh, но могут использовать их для аутентификации на другом компьютере, пока выполняется команда ssh
.
Вам потребуется доступ с действительным пользователем, не только из-за ssh auth, но и из-за прав доступа и владения файлами.
Мне очень нравится rsync
для передачи данных по сети. Инкрементная передача данных может быть возобновлена, что очень важно, когда у вас нет полного контроля над сетевым соединением между двумя серверами