Вы должны знать, что Wine - это не песочница . Программы, работающие под Wine, не ограничиваются Windows API; Теоретически вирус, осведомленный о Wine, может легко обнаружить, что он работает под Wine, и переключиться на использование API хоста (например, Linux), чтобы нанести столько же вреда, сколько вредоносное ПО для Linux.
Самый надежный способ изоляции - полная виртуальная машина. Менее полными (но, возможно, более практичными) способами было бы запустить программу под Wine внутри chroot или контейнера, однако при этом ядро хоста остается открытым.
Если я правильно понял, я думаю, что вы хотите в основном перебирать списки значений, а затем read
еще одно в цикле.
Вот несколько вариантов, 1 и 2, наверное, самые разумные.
1. Эмулировать массивы строками
Было бы неплохо иметь 2D-массивы, но в Bash это невозможно. Если в ваших значениях нет пробелов, один обходной путь для аппроксимации состоит в том, чтобы вставить каждый набор из трех чисел в строку и разделить строки внутри цикла:
for x in "1 2 3" "4 5 6"; do
read a b c <<< "$x";
read -p "Enter a number: " d
echo "$a - $b - $c - $d ";
done
Конечно, можно использовать и другой разделитель, например. for x in 1:2:3...
и IFS=: read a b c <<< "$x"
.
2. Заменить канал другим перенаправлением на свободный стандартный ввод
Другая возможность состоит в том, чтобы read a b c
читался из другого fd и направлял ввод в этот (это должно работать в стандартной оболочке):
while read a b c <&3; do
printf "Enter a number: "
read d
echo "$a - $b - $c - $d ";
done 3<<EOF
1 2 3
4 5 6
EOF
И здесь вы также можете использовать подстановку процесса, если хотите получить данные из команды:while read a b c <&3;...done 3< <(echo $'1 2 3\n4 5 6')
(подстановка процесса — это функция bash/ksh/zsh)
3. Вместо этого брать пользовательский ввод из stderr
Или, наоборот, используя канал, как в вашем примере, но вводите пользовательский ввод read
изstderr
(fd 2 )вместо stdin
, откуда идет канал:
echo $'1 2 3\n4 5 6' |
while read a b c; do
read -u 2 -p "Enter a number: " d
echo "$a - $b - $c - $d ";
done
Чтение из stderr
немного странно, но на самом деле часто работает в интерактивном сеансе. (Вы также можете явно открыть /dev/tty
, предполагая, что вы действительно хотите обойти любые перенаправления, это то, что такие вещи, как less
, используют для получения ввода пользователя, даже если данные передаются ему.)
Хотя использование stderr
таким образом может работать не во всех случаях, и если вы используете какую-то внешнюю команду вместо read
, вам, по крайней мере, потребуется добавить к команде несколько перенаправлений.
Также см. Почему моя переменная локальна в одном цикле while read, но не в другом похожем цикле? по некоторым вопросам, касающимся ... | while
.
4. Разрезать части массива по мере необходимости
Я полагаю, вы также можете аппроксимировать двумерный -массив путем копирования срезов обычного -многомерного:
data=(1 2 3
4 5 6)
n=3
for ((i=0; i < "${#data[@]}"; i += n)); do
a=( "${data[@]:i:n}" )
read -p "Enter a number: " d
echo "${a[0]} - ${a[1]} - ${a[2]} - $d "
done
Вы также можете назначить ${a[0]}
и т. д. на a
, b
и т. д., если вам нужны имена для переменных, но Zsh сделает это намного лучше .
С помощью zsh
вы можете вместо этого написать:
for a b c (
1 2 3
4 5 6
'more complex' $'\n\n' '*** values ***'
) {
read 'd?Enter a number: '
do-something-with $a $b $c $d
}
Для двумерных массивов см. также оболочку ksh93
:
a=(
(1 2 3)
(4 5 6)
('more complex' $'\n\n' '*** values ***')
)
for i in "${!a[@]}"; do
read 'd?Enter a number: '
do-something-with "${a[i][0]}" "${a[i][1]}" "${a[i][2]}" "$d"
done