0

commrads! I have a file:

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

and i need execute line by line:

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

BUT! The file has special content like: ' \. . and etc. And when i start my script with "set -x" i see this:

+ 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'\'''

IN THE IDEAL MUST BE:

/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'

I think it's all from special content (file). Any ideas?

1 Answers1

3

Yes, when you iterate over the output of cat file, you iterate over the words.

One solution:

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

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

This will read the lines, one by one, and properly read the backslashes and the spaces between the words. Notice the quoting of $line. See "Understanding "IFS= read -r line"".

I originally included a version using xargs, but I noticed that this did not preserve the backslashes in the file data under some circumstances, and stripped away the single quotes.

Kusalananda
  • 333,661
  • 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 ''''\.\Aktiv' Co. Rutoken S 00 '00\D.KLEMENTEV@R69-20180109''''

    Error

    • IFS=
    • read -r words
    – Oleg Kalinin May 28 '18 at 09:13
  • @OlegKalinin It's difficult to read that, but it looks like you swapped two directories (bin and amd64) when you're setting the path. – Kusalananda May 28 '18 at 09:46
  • use set -x and see this: ''\''\\.\Aktiv' Co. Rutoken S 00 '00\D.KLEMENTEV@R69-20180109'\''' but it is not correct. This wil be correct: – Oleg Kalinin May 28 '18 at 11:18
  • @OlegKalinin Note that the tracing output of set -x may add and remove quotes from the actual command being executed. You should use printf '%s\n' "$line" to see what the actual string passed to the utility is. If you double quote the expansion of $line on the command line (as I have done), the correct data will be passed to the utility. – Kusalananda May 28 '18 at 11:29
  • With "$line" (double quote the expansion) analogous situation. I did like this: Aktiv=$(cat file) cat <<- EOF > final_file /opt/cprocsp/bin/amd64/certmgr -inst -cont ${Aktiv} EOF bash final_file and I achieved the result. But in this situation i have 1 line in file. In this situation # cat file '\\.\Aktiv Co. Rutoken S 00 00\USER1@R69-20180109' '\\.\Aktiv Co. Rutoken S 00 01\USER2@R69-20180109' – Oleg Kalinin May 28 '18 at 13:44
  • @OlegKalinin I don't understand. Are you saying that the solution that I posted does not work? I really can't see how yours would work as $Aktiv is not even quoted in the here-document. – Kusalananda May 28 '18 at 14:37