Во-первых, не читайте строки с для, поскольку существует несколько неизбежных проблем с чтением строк через разделение слова.
Принятие файлов равной длины, или если Вы хотите только к циклу до короче двух файлов, читается, простое решение возможно.
while read -r x && read -r y <&3; do
...
done
Соединение более общего решения трудно из-за когда read
возвращает false и несколько других причин. Этот пример может считать произвольное число потоков и возврата или после самого короткого или после самого длинного входа.
#!/usr/bin/env bash
# Open the given files and assign the resulting FDs to arrName.
# openFDs arrname file1 [file2 ...]
openFDs() {
local x y i arr=$1
[[ -v $arr ]] || return 1
shift
for x; do
{ exec {y}<"$x"; } 2>/dev/null || return 1
printf -v "${arr}[i++]" %d "$y"
done
}
# closeFDs FD1 [FD2 ...]
closeFDs() {
local x
for x; do
exec {x}<&-
done
}
# Read one line from each of the given FDs and assign the output to arrName.
# If the first argument is -l, returns false only when all FDs reach EOF.
# readN [ -l ] arrName FD1 [FD2 ...]
readN() {
if [[ $1 == -l ]]; then
local longest
shift
else
local longest=
fi
local i x y status arr=$1
[[ -v $arr ]] || return 1
shift
for x; do
if IFS= read -ru "$x" "${arr}[i]" || { unset -v "${arr}[i]"; [[ ${longest+_} ]] && return 1; }; then
status=0
fi
((i++))
done
return ${status:-1}
}
# readLines file1 [file2 ...]
readLines() {
local -a fds lines
trap 'closeFDs "${fds[@]}"' RETURN
openFDs fds "$@" || return 1
while readN -l lines "${fds[@]}"; do
printf '%-1s ' "${lines[@]}"
echo
done
}
{
readLines /dev/fd/{3..6} || { echo 'error occured' >&2; exit 1; }
} <<<$'a\nb\nc\nd' 3<&0 <<<$'1\n2\n3\n4\n5' 4<&0 <<<$'x\ny\nz' 5<&0 <<<$'7\n8\n9\n10\n11\n12' 6<&0
# vim: set fenc=utf-8 ff=unix ts=4 sts=4 sw=4 ft=sh nowrap et:
Таким образом, в зависимости от ли readN
добирается -l
, вывод также
a 1 x 7
b 2 y 8
c 3 z 9
d 4 10
5 11
12
или
a 1 x 7
b 2 y 8
c 3 z 9
Необходимость считать несколько потоков в цикле, не сохраняя все в несколько массивов не является всем этим распространенным. Если Вы просто хотите считать массивы, необходимо взглянуть на mapfile
.
Попробуйте это:
ssh user@remotehost.domain sudo cat /path/to/restricted_file > /local/path
Если Ваш sudo
требует ввода в пароле, который Вы захотите добавить -t
сразу после ssh
для ввода sudo
пароль.
То, что это делает, выполняется sudo cat file
на удаленном хосте, перенаправляя вывод в локальный файл. На Вашей локальной машине файл будет создан Вашей оболочкой с полномочиями локального пользователя.
Необходимо смочь сделать это путем вхождения в систему удаленной машины с ssh
и затем запуск scp
команда от удаленной машины до Вашей локальной:
ssh user@remote sudo scp /path/to/file user@local.machine.com:/local/path
scp
если Вы ssh
к серверу и затем переключаются на корень? Необходимо будет также сделать локальный компьютер доступным вводным портом 22 на маршрутизаторе и перенаправлении его к машине.
– terdon♦
26.06.2013, 17:53
ssh
соединения: локальный для удаленной и удаленной спины к локальному. Другими словами, обе машины должны иметь ssh
выполнение серверов и доступный. См. мой ответ для простого решения.
– jw013
26.06.2013, 18:36
мне лично нужно было собрать несколько файлов Я мог читать только с помощью sudo, и я хотел сделать это за один раз.
ssh user@remote 'cd /path/to; sudo tar zcvf - files*' > files.tar.gz
Оттуда вам просто нужно заархивировать файл и получить все нужные файлы.