Ubuntu (14 & 16) Bash 来自包含小写 "n" 字符的输入的 printf 循环错误
Ubuntu (14 & 16) Bash errors with printf loops from input containing lowercase "n" characters
我有一些 bash 脚本我已经 运行 在 Ubuntu 14.04 和 16.04 上使用了一年多了。最近的一些 Ubuntu 更新已损坏 bash,我不知道如何解决这个问题。
示例:
#!/bin/bash
INPUT=myinput.txt
OUTPUT=myoutput.txt
ACTION1="0;"
cat $INPUT | while read LINE
do
printf "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
done
我的脚本然后循环执行 printf 语句的文件如下,但这是产生的输出
"~jetmo" 0;
"~spamme" 0;
"~baidu" 0;
myinput.txt
的示例内容
jetmon
spammen
baidu
包含小写 n 字符的输入行被删除了??
我是否错过了 bash 发生的一些重大变化,这发生在一周前,现在让我发疯。
我尝试将 #!/bin/bash 更改为 #!/bin/sh,结果相同。
也试过这种循环遍历输入文件的方法,仍然得到相同的结果。
#!/bin/bash
INPUT=myinput.txt
OUTPUT=myoutput.txt
ACTION1="0;"
while read LINE
do
printf "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
done < $INPUT
尝试使用 echo
评论中的建议
echo -e -n "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
现在我得到了这个输出
-e -n "~jetmo" 0;
-e -n "~spamme" 0;
-e -n "~baidu" 0;
运行 hexdump -C myinput.txt 给出了这个输出
00000000 6a 65 74 6d 6f 6e 0a 73 70 61 6d 6d 65 6e 0a 62 |jetmon.spammen.b|
00000010 61 69 64 75 0a 0a |aidu..|
00000016
还按照 Michael 的建议将所有变量名称更改为小写,但仍然得到相同的结果。
#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
cat $input | while read line
do
printf "\t\"~${line}\"\t\t$action1\n" >> $output
done
解决方案
谜底已解
感谢大家,但是https://whosebug.com/users/96588/l0b0一语中的。我的脚本中早些时候隐藏了一个 IFS=$'\n'
。
感谢 Nahuel 和 Charles 的推荐,我现在有了最终的、更好的、更安全的 printf 格式,它 100% 正常工作……非常感谢你们。
#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
while IFS= read -r LINE
do
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$output"
done < $input1
如果它可以包含 %
,则使用 %s
插入带有 printf 的字符串会更安全
printf "\t\"~%s\"\t\t%s\n" "${LINE}" "$ACTION1" >> $OUTPUT
编辑以下评论,在第一个参数中使用单引号,因为没有变量扩展
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$OUTPUT"
如果内部字段分隔符 ($IFS
) 包含字母 n
:
,就会发生这种情况
$ IFS=$' \t\nn' read line <<< foon
$ printf '%q\n' "$line"
foo
这是相当常见的 mistake。这是正确的值:
$ printf '%q\n' "$IFS"
$' \t\n'
示例:
$ IFS=$' \t\n' read line <<< foon
$ printf '%q\n' "$line"
foon
解决方案
谜底已解
感谢大家,但是https://whosebug.com/users/96588/l0b0一语中的。我的脚本中早些时候隐藏了一个 IFS=$'\n'
。
感谢 Nahuel 和 Charles 的建议,我现在有了最终的、更好的和更安全的 printf 格式,它正在 100% 工作......非常感谢你们。
#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
while IFS= read -r LINE
do
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$output"
done < $input1
我有一些 bash 脚本我已经 运行 在 Ubuntu 14.04 和 16.04 上使用了一年多了。最近的一些 Ubuntu 更新已损坏 bash,我不知道如何解决这个问题。
示例:
#!/bin/bash
INPUT=myinput.txt
OUTPUT=myoutput.txt
ACTION1="0;"
cat $INPUT | while read LINE
do
printf "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
done
我的脚本然后循环执行 printf 语句的文件如下,但这是产生的输出
"~jetmo" 0;
"~spamme" 0;
"~baidu" 0;
myinput.txt
的示例内容jetmon
spammen
baidu
包含小写 n 字符的输入行被删除了?? 我是否错过了 bash 发生的一些重大变化,这发生在一周前,现在让我发疯。
我尝试将 #!/bin/bash 更改为 #!/bin/sh,结果相同。
也试过这种循环遍历输入文件的方法,仍然得到相同的结果。
#!/bin/bash
INPUT=myinput.txt
OUTPUT=myoutput.txt
ACTION1="0;"
while read LINE
do
printf "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
done < $INPUT
尝试使用 echo
评论中的建议echo -e -n "\t\"~${LINE}\"\t\t$ACTION1\n" >> $OUTPUT
现在我得到了这个输出
-e -n "~jetmo" 0;
-e -n "~spamme" 0;
-e -n "~baidu" 0;
运行 hexdump -C myinput.txt 给出了这个输出
00000000 6a 65 74 6d 6f 6e 0a 73 70 61 6d 6d 65 6e 0a 62 |jetmon.spammen.b|
00000010 61 69 64 75 0a 0a |aidu..|
00000016
还按照 Michael 的建议将所有变量名称更改为小写,但仍然得到相同的结果。
#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
cat $input | while read line
do
printf "\t\"~${line}\"\t\t$action1\n" >> $output
done
解决方案 谜底已解
感谢大家,但是https://whosebug.com/users/96588/l0b0一语中的。我的脚本中早些时候隐藏了一个 IFS=$'\n'
。
感谢 Nahuel 和 Charles 的推荐,我现在有了最终的、更好的、更安全的 printf 格式,它 100% 正常工作……非常感谢你们。
#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
while IFS= read -r LINE
do
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$output"
done < $input1
如果它可以包含 %
%s
插入带有 printf 的字符串会更安全
printf "\t\"~%s\"\t\t%s\n" "${LINE}" "$ACTION1" >> $OUTPUT
编辑以下评论,在第一个参数中使用单引号,因为没有变量扩展
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$OUTPUT"
如果内部字段分隔符 ($IFS
) 包含字母 n
:
$ IFS=$' \t\nn' read line <<< foon
$ printf '%q\n' "$line"
foo
这是相当常见的 mistake。这是正确的值:
$ printf '%q\n' "$IFS"
$' \t\n'
示例:
$ IFS=$' \t\n' read line <<< foon
$ printf '%q\n' "$line"
foon
解决方案 谜底已解
感谢大家,但是https://whosebug.com/users/96588/l0b0一语中的。我的脚本中早些时候隐藏了一个 IFS=$'\n'
。
感谢 Nahuel 和 Charles 的建议,我现在有了最终的、更好的和更安全的 printf 格式,它正在 100% 工作......非常感谢你们。
#!/bin/bash
input=myinput.txt
output=myoutput.txt
action1="0;"
while IFS= read -r LINE
do
printf '\t"~%s"\t\t%s\n' "${LINE}" "$ACTION1" >> "$output"
done < $input1