当bash脚本以root用户身份运行时,为什么硬编码字符串变量会发生变化?

当bash脚本以root用户身份运行时,为什么硬编码字符串变量会发生变化?,bash,path,Bash,Path,我正在使用ufraw使用快速而肮脏的bash脚本批量转换一些图片: IFS=$'\n' PICS="/media/disk/kevin/Images/"; for pic in $(find $PICS -name "*CR2"); do ufraw-batch $pic --out-type jpg --size=2048 --overwrite --out-path=$PICS; rm -f $pic done; IFS=" "; 它可以正常运行,但如果我使用: sudo.

我正在使用ufraw使用快速而肮脏的bash脚本批量转换一些图片:

IFS=$'\n'
PICS="/media/disk/kevin/Images/";
for pic in $(find $PICS -name "*CR2");
do
    ufraw-batch $pic --out-type jpg --size=2048 --overwrite --out-path=$PICS;
    rm -f $pic
done;
IFS=" ";
它可以正常运行,但如果我使用:

sudo./convert.sh

我犯了一个奇怪的错误:

find: "/media/disk/kevi" : no such file or directory.
我做到了:

IFS=$'\n'
PICS="/media/disk/kevin/Images/";
echo PICS;
然后我惊讶地发现:

/media/disk/kevi /Images/

WTF?

你的
$IFS
“n”
;它不是将
\n
解释为一个新行,而是一个无意义的转义
n
。我隐约怀疑您遇到了某种针对root用户的
$IFS
的文档保护(因为这是一个众所周知的漏洞向量),但您可能希望尝试使用ctrl-v enter在脚本中嵌入文字换行符而不是符号换行符。

您的
$IFS
“n”
;它不是将
\n
解释为一个新行,而是一个无意义的转义
n
。我隐约怀疑您遇到了对root的
$IFS
的某种文档保护(因为这是一个众所周知的漏洞向量),但您可能希望尝试使用ctrl-v enter在脚本中嵌入文字换行符,而不是符号换行符。

您的代码似乎有输入错误。如果实际代码为IFS='\n'或IFS=“\n”,则已将分隔符设置为两个字符的列表,\n和。如果IFS=\n,则POSIX shell中的一个字符\n不能解释为LF。它与根无关

$ BLAH='\n'
$ echo $BLAH
\n
$ BLAH="\n"
$ echo $BLAH
\n
$ BLAH=\n
$ echo $BLAH
n
$ BLAH="Both\n\and\aregone"
$ echo $BLAH
Both   a d arego e

您的代码似乎有输入错误。如果实际代码为IFS='\n'或IFS=“\n”,则已将分隔符设置为两个字符的列表,\n和。如果IFS=\n,则POSIX shell中的一个字符\n不能解释为LF。它与根无关

$ BLAH='\n'
$ echo $BLAH
\n
$ BLAH="\n"
$ echo $BLAH
\n
$ BLAH=\n
$ echo $BLAH
n
$ BLAH="Both\n\and\aregone"
$ echo $BLAH
Both   a d arego e

如果您没有明确的
#行在脚本中,sudo ed命令很可能是在
/bin/sh
下运行的,而不是在
/bin/bash
下运行的。如果您是在最近的Linux系统上运行,那么
/bin/sh
很可能是
dash
而不是
bash
。dash的维护者认为IFS不应该解释转义序列(例如,请参见此处的


因此,您看到的行为仅与在根目录下运行间接相关。如果显式使用dash,您将看到相同的结果。解决这个问题的另一种方法是包含一个解释性的
#/在脚本中使用bin/bash

如果没有解释
#行在脚本中,sudo ed命令很可能是在
/bin/sh
下运行的,而不是在
/bin/bash
下运行的。如果您是在最近的Linux系统上运行,那么
/bin/sh
很可能是
dash
而不是
bash
。dash的维护者认为IFS不应该解释转义序列(例如,请参见此处的


因此,您看到的行为仅与在根目录下运行间接相关。如果显式使用dash,您将看到相同的结果。解决这个问题的另一种方法是包含一个解释性的
#/bin/bash
在您的脚本中。

非常感谢。事实上,IFS似乎是为根而保护的,使用一个字面上的新行就像一个符咒。实际上,这与根无关。阅读转义字符()的Shell命令语言描述。该引用没有帮助,因为它没有描述您在这里使用的ANSI-C引号($'..)。对不起,我错了。嗨,混乱,我要接受内德的回答,因为他在解释“为什么”。谢谢你帮我很快解决了这个问题。非常感谢。事实上,IFS似乎是为根而保护的,使用一个字面上的新行就像一个符咒。实际上,这与根无关。阅读转义字符()的Shell命令语言描述。该引用没有帮助,因为它没有描述您在这里使用的ANSI-C引号($'..)。对不起,我错了。嗨,混乱,我要接受内德的回答,因为他在解释“为什么”。感谢您帮助我快速解决这个问题。正如我所写的,这个脚本运行良好,路径显示良好,但没有管理员权限。如果我去掉IFS替换项,脚本将不起作用,因为IFS是一个空间,我的循环将在包含任何空间的音调化路径上结束。顺便说一句,这不是IFS='\n',而是FS=$'\n'。这是非常不同的。对不起,我误解了你的例子中ANSI-C引用的用法,所以这个答案是不相关的。请参阅最新的答案以获得更可能的解释。正如我所写的,这个脚本运行良好,路径显示良好,没有管理员权限。如果我去掉IFS替换项,脚本将不起作用,因为IFS是一个空间,我的循环将在包含任何空间的音调化路径上结束。顺便说一句,这不是IFS='\n',而是FS=$'\n'。这是非常不同的。对不起,我误解了你的例子中ANSI-C引用的用法,所以这个答案是不相关的。查看最近的答案,以获得更可能的解释。经过测试,事实上,这似乎是正确的。我转换了被接受的答案,感谢你不仅接受了你的错误,而且在之后努力做出贡献。谢谢!我发现很难相信问题出在sudo身上,我自己也学到了一些新的东西。经过测试,事实上,似乎就是这样。我转换了被接受的答案,感谢你不仅接受了你的错误,而且在之后努力做出贡献。谢谢!我发现很难相信问题出在sudo身上,我自己也学到了一些新东西。