我在一个变量中有一个 unix 命令,它看起来像这样:
cmd="find /path/to/webpage -type f | grep -v .svn | xargs grep $@"
`$cmd`
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]
Run Code Online (Sandbox Code Playgroud)
当我尝试$cmd
在 bash 脚本中执行命令时,它不起作用。但是,当我复制并粘贴完全相同的命令时,它确实有效。你能告诉我我做错了什么吗?
我试过在路径周围加上引号,发生同样的错误
cmd="find \"/path/to/webpage\" -type f | grep -v .svn | xargs grep $@"
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]
Run Code Online (Sandbox Code Playgroud)
当我删除-type f
参数时,出现此错误:
cmd="find /path/to/webpage | grep -v .svn | xargs grep $@"
find: invalid predicate `-v'
Run Code Online (Sandbox Code Playgroud)
这让我认为管道没有被识别。我该怎么做才能让它发挥作用?
其他人已经解释了该怎么做。让我解释一下这里发生的事情:管道字符|
不会在变量扩展时形成管道,而是像文字字符一样起作用。因此,find
使用以下参数执行:
{"/path/to/webpage", "-type", "f", "|", "grep", "-v", ".svn", "|", ...}
Run Code Online (Sandbox Code Playgroud)
并将 the 解释|
为路径并抱怨它应该出现在表达式 ( -type f
)之前。
另一个大错误是您将其`$cmd`
用作唯一的命令行。如果$cmd
(ie find ...
) 成功并产生类似 的输出rm -rf /
,它将代表您执行。当您将数据作为代码时,请务必小心!
改进 1. find ... | grep -v ...
是一种从输出中排除某些内容的糟糕方法:find
将遍历名为 的整个子目录.svn
,生成行,稍后将被丢弃。为什么不find
直接告诉做呢?
find path -type f | grep -v .svn # don't do this
find path -name .svn -prune -o -type f -print # do this instead
Run Code Online (Sandbox Code Playgroud)
改进 2.组合find
and 时xargs
,始终使用-print0
infind
和-0
in xargs
:
find path ... -print0 | xargs -0 -r grep ... # I'd also recommend -r
Run Code Online (Sandbox Code Playgroud)
或者你可以完全在grep
:
grep --recursive --exclude-dir=.svn pattern path
Run Code Online (Sandbox Code Playgroud)
如果你真的想在一个变量中执行代码,你可以使用eval
.
cmd="find /path/to/webpage -type f | grep -v .svn | xargs grep something"
eval "$cmd"
Run Code Online (Sandbox Code Playgroud)
但是由于您尝试使用 with 传递参数$@
,因此您需要的是一个函数
webgrep() {
find /path/to/webpage -type f | grep -v .svn | xargs grep "$@"
}
Run Code Online (Sandbox Code Playgroud)
请注意,任何包含空格字符的路径都会出现问题。或以减号开头的模式。它必须先扫描.svn
目录的所有内容,然后再忽略它们。处理用户意外传递多个参数会很好(例如,因为模式没有正确引用)。更好的方法是
webgrep() {
find /path/to/webpage -name .svn -prune -o -type f -exec grep -e "$*" {} +
}
Run Code Online (Sandbox Code Playgroud)
然后这样调用
webgrep PATTERN
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11298 次 |
最近记录: |