Странная проблема с передачей переменных из текстового файла

Странная проблема с передачей переменных из текстового файла

У меня есть скрипт, который запускает другой скрипт для каждой строки в файле.

Когда я echoкаждый раз $lineвижу полное содержимое строки, как и ожидалось.

Однако внутри установлено connect.shтолько .$1user\ name

Когда я пытаюсь использовать "$line", $1в connect.shитоге получается user\ name user\ password.

Как настроить поток программы так, чтобы reboot.shкаждая строка передавалась /tmp/historyкак connect.sh2 параметра?

Что в итоге $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"

Просто помните, что если вы передаете аргумент программе и этот аргумент содержит пробелы, вам нужно будет использовать двойные кавычки, чтобы программа воспринимала его как один аргумент.

Связанный контент