下午好,我有以下命令运行'code.sh'文件,我传递参数'$ 1'问题是我想用'source'运行'code.sh'这是我的命令:
find . -name "*.txt" -type f -exec ./code.sh {} \;
我做得很好
source ./code.sh
答案 0 :(得分:3)
这很棘手。当您source
脚本时,您需要在当前shell中执行此操作,而不是在子shell或子进程中执行此操作。从source
执行find
无法正常工作,因为find
是子进程,因此对环境变量的更改将会丢失。
它相当迂回,但您可以使用循环来解析find
的输出并直接在顶级shell中运行source
命令(使用{{ 3}})。
while read -d $'\0' fileName; do
source code.sh "$fileName"
done < <(find . -name "*.txt" -type f -print0)
现在你问-print0
和-d $'\0'
了什么?一起使用这两个标志是一种使脚本更加安全的方法。†允许UNIX中的文件名包含许多古怪字符,包括空格,制表符甚至换行符。虽然换行很少见,但它们确实合法。
-print0
告诉find
使用NUL字符(\0
)来分隔文件名而不是默认换行符(\n
)。这样做意味着包含\n
的文件名不会弄乱循环。使用\0
作为分隔符很有效,因为\0
不是文件名中的合法字符。
-d $'\0'
‡在另一方与read
做同样的事情。它告诉read
这些行以\0
而不是\n
分隔。
†您之前可能已经看过这个技巧了。在find ... -print0 | xargs -0 ...
与find
配对时,写xargs
以获得相同的安全性是很常见的。
‡如果您想知道$'...'
:用于编写包含转义码的字符串文字的Bash process substitution语法。美元符号加单引号。您可以为换行符写$'\n'
,为标签添加$'\t'
或为NUL写$'\0'
。
答案 1 :(得分:2)
您将无法以这种方式使用find
;它将始终在单独的进程中执行命令,而不是当前的shell。如果您使用的是bash
4,则可以选择使用find
:
shopt -s globstar
for f in **/*.txt; do
[[ -f $f ]] && source code.sh "$f"
done