У меня есть скрипт, который запускает другой скрипт для каждой строки в файле.
Когда я echo
каждый раз $line
вижу полное содержимое строки, как и ожидалось.
Однако внутри установлено connect.sh
только .$1
user\ name
Когда я пытаюсь использовать "$line"
, $1
в connect.sh
итоге получается user\ name user\ password
.
Как настроить поток программы так, чтобы reboot.sh
каждая строка передавалась /tmp/history
как connect.sh
2 параметра?
Что в итоге $1
получается user\ name
и $2
есть user\ password
?
перезагрузка.sh:
if [ -e "/tmp/history" ]; then
while read -r line; do
echo $line
connect.sh $line \
&& break
done </tmp/history
fi
connect.sh:
echo $1
echo $2
/tmp/история:
user\ name user\ password
решение1
Я предполагаю, что обратные косые черты нужны для того, чтобы экранировать два пробела и не разделять значения.
С read -r line
вы получаете всю строку в переменной line
, так что она line
содержит user\ name user\ password
, с забоями. Это нелегко разделить без трюков с eval
. Незаключенный в кавычки $line
будет разделен на пробелы, с обратными косыми чертами или без них. Заключенный в кавычки, он расширяется в одно слово, как вы видели.
К счастью, read
может обрабатывать обратные косые черты и разделять свой ввод на две (или более) переменных. Это будет иметь переменные, содержащие user name
и user password
(с удаленными обратными косыми чертами):
while read user pass ; do
echo "user: $user"
echo "pass: $pass"
./connect.sh "$user" "$pass"
done < file
Однако, если вы хотите разрешить пробелы в имени пользователя и пароле, может быть лучше использовать какой-то другой разделитель, а не пробел. Двоеточие является обычным, поэтому у вас будет такой ввод:
user name:user pass word
А затем прочитайте это с
while IFS=: read -r user pass ; do
echo "user: $user"
echo "pass: $pass"
done < file
(Это должно сработать, если пароль не заканчивается двоеточием)
решение2
Если у вас есть аргумент с пробелами, вам нужно будет убедиться, что вы заключили строку в двойные кавычки, чтобы предотвратить connect.sh
ее интерпретацию как нескольких аргументов. Вы можете захотеть разделить строку на несколько аргументов. Я не уверен, каков формат строки, но вы можете сделать что-то вроде этого:
line="user name user password"
# Split the line into space-separated tokens and store 1 and 2
UNAME=$(echo "$line" | cut -d ' ' -f 1,2)
# Split the line into space-separated tokens and store 3 and 4
UPASSWD=$(echo "$line" | cut -d ' ' -f 3,4)
echo "$UNAME"
echo "$UPASSWD"
Это должно напечатать:
user name
user password
Вам, вероятно, придется внести некоторые изменения, основанные на фактическом формате входной строки. Например, если ваша $line содержит имя пользователя и пароль пользователя, разделенные запятой, вы можете запустить:
line="user name,user password"
# Split the line into comma-separated tokens and store 1
UNAME=$(echo "$line" | cut -d ',' -f 1)
# Split the line into comma-separated tokens and store 2
UPASSWD=$(echo "$line" | cut -d ',' -f 2)
echo "$UNAME"
echo "$UPASSWD"
Просто помните, что если вы передаете аргумент программе и этот аргумент содержит пробелы, вам нужно будет использовать двойные кавычки, чтобы программа воспринимала его как один аргумент.