Товарищи! У меня есть файл:

# cat file
'\\.\Aktiv Co. Rutoken S 00 00\USER1@R69-20180109'
'\\.\Aktiv Co. Rutoken S 00 01\USER2@R69-20180109'

И мне нужно выполнить построчно:

for LINE in `cat file` 
do
/opt/cprocsp/bin/amd64/certmgr -inst -cont $LINE
done

НО! Файл имеет специальное содержимое, например: ' \. . и т. д. И когда я запускаю свой скрипт с помощью «set -x», я вижу это:

+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont ''\''\\.\Aktiv'
Error
+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont Co.
Error
+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont Rutoken
Error
+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont S
Error
+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont 00
Error
+ for LINE in '`cat /home/user/Aktiv`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont '00\USER1@R69-20180109'\'''
+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont ''\''\\.\Aktiv'
Error
+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont Co.
Error
+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont Rutoken
Error
+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont S
Error
+ for LINE in '`cat file`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont 00
Error
+ for LINE in '`cat /home/user/Aktiv`'
+ /opt/cprocsp/bin/amd64/certmgr -inst -cont '01\USER2@R69-20180109'\'''

В ИДЕАЛЕ ДОЛЖНЫ БЫТЬ:

/opt/cprocsp/bin/amd64/certmgr -inst -cont '\\.\Aktiv Co. Rutoken S 00 00\USER1@R69-20180109'
/opt/cprocsp/bin/amd64/certmgr -inst -cont '\\.\Aktiv Co. Rutoken S 00 01\USER2@R69-20180109'

Я думаю, это все из-за специального контента (файла). Любые идеи?

0
Oleg Kalinin 25 Май 2018 в 16:16
1
for не работает построчно.
 – 
Ignacio Vazquez-Abrams
25 Май 2018 в 16:19
Это часто задаваемые вопросы: Как прочитать файл построчно
 – 
glenn jackman
25 Май 2018 в 18:29

1 ответ

Лучший ответ

Да, когда вы перебираете вывод cat file, вы перебираете слова.

Одно решение:

PATH=/opt/cprocsp/bin/amd64:$PATH

while IFS= read -r line; do
    certmgr -inst -cont "$line"
done <file

Это будет читать строки одну за другой и правильно читать обратную косую черту и пробелы между словами. Обратите внимание на цитирование $line. См. «Понимание строки «IFS= read -r»».

Первоначально я включил версию, использующую xargs, но заметил, что при некоторых обстоятельствах это не сохраняет обратную косую черту в данных file, и убирает одинарные кавычки.

3
Kusalananda 25 Май 2018 в 18:29
# sh script.sh + PATH=/opt/cprocsp/bin/amd64:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin: /usr/sbin:/sbin:/home/user/bin + IFS= + read -r words + certmgr -inst -cont ''\''\\.\Актив' Ко. Рутокен С 00 '00\Д.КЛЕМЕНТЕВ @ R69-20180109'\''' Ошибка + IFS= + чтение -r слов
 – 
Oleg Kalinin
28 Май 2018 в 12:13
Это трудно прочитать, но похоже, что вы поменяли местами два каталога (bin и amd64) при установке пути.
 – 
Kusalananda
28 Май 2018 в 12:46
Используйте set -x и увидите это: ''\''\\.\Aktiv' Co. Rutoken S 00 '00\D.KLEMENTEV@R69-20180109'\''', но это неправильно. Это будет правильно:
 – 
Oleg Kalinin
28 Май 2018 в 14:18
Обратите внимание, что вывод трассировки set -x может добавлять и удалять кавычки из фактической выполняемой команды. Вы должны использовать printf '%s\n' "$line", чтобы увидеть, что такое фактическая строка, переданная утилите. Если вы дважды закавычите расширение $line в командной строке (как я сделал), правильные данные будут переданы утилите.
 – 
Kusalananda
28 Май 2018 в 14:29
Аналогичная ситуация с "$line" (расширение в двойных кавычках). Я сделал так: Aktiv=$(cat file) cat <<- EOF > final_file /opt/cprocsp/bin/amd64/certmgr -inst -cont ${Aktiv} EOF bash final_file и добился результата. Но в этой ситуации у меня есть 1 строка в файле. В этой ситуации # cat file '\\.\Aktiv Co. Rutoken S 00 00\USER1@R69-20180109' '\\.\Aktiv Co. Rutoken S 00 01\USER2@R69-20180109'
 – 
Oleg Kalinin
28 Май 2018 в 16:44