Regex 隐藏cat提示错误
我想设置一个脚本,以便连续解析xml文件中的特定标记 脚本包含以下Regex 隐藏cat提示错误,regex,linux,bash,shell,cat,Regex,Linux,Bash,Shell,Cat,我想设置一个脚本,以便连续解析xml文件中的特定标记 脚本包含以下while循环: function scan_t() { INPUT_FILE=${1} while : ; do if [[ -f "$INPUT_FILE" ]] then ret=`cat ${INPUT_FILE} | grep "<data>" | awk -F"=|>" '{print $2}' | awk -F"=|<" '{print $1}'` if [
while
循环:
function scan_t()
{
INPUT_FILE=${1}
while : ; do
if [[ -f "$INPUT_FILE" ]]
then
ret=`cat ${INPUT_FILE} | grep "<data>" | awk -F"=|>" '{print $2}' | awk -F"=|<" '{print $1}'`
if [[ "$ret" -ne 0 ]] && [[ -n "$ret" ]]
then
...
fi
fi
done
}
scant_t "/tmp/test.xml"
功能扫描
{
输入文件=${1}
当:;做
如果[-f“$INPUT_文件”]]
然后
ret=`cat${INPUT_FILE}| grep”“| awk-F”“=|>“{print$2}”| awk-F”“=|如果其他进程也可以在脚本看到该文件之前读取并删除该文件,那么您的系统就设计了一个争用条件(我假设“charged to suppress”意味着“设计为取消链接”)
如果此脚本可以选择查看每个输入文件,则只需将stderr重定向到/dev/null
(即,当竞争条件生效时忽略错误)。如果不是可选的,则让此脚本将输入文件重命名为其他文件,并让其他进程监视该文件。在重命名之前,请检查该文件是否存在,以确保不会覆盖其他进程尚未读取的文件
你的循环有一个糟糕的设计。首先,你正忙着等待(根本没有睡眠
)文件的出现。其次,当输入存在时,你正在运行4个程序,而不是1个
通过使用inotifywait
监视目录的更改,可以避免繁忙的等待。因此if[[-f$INPUT\u FILE]]
循环体仅在修改目录后运行,而不是以CPU核心可以运行的速度运行
第二个更容易处理:永远不要cat file | something
。如果something
命令行上没有文件名,或者行为不同,则cat
只有在有多个文件要连接时才有用。用于将文件读入Shelll变量,使用foo=$(如果其他进程也可以在脚本看到该文件之前读取并删除该文件,那么您的系统就设计了一个竞争条件。(我假设“充电以抑制”表示“设计为取消链接”。)
如果此脚本可以选择查看每个输入文件,则只需将stderr重定向到/dev/null
(即,当竞争条件生效时忽略错误)。如果不是可选的,则让此脚本将输入文件重命名为其他文件,并让其他进程监视该文件。在重命名之前,请检查该文件是否存在,以确保不会覆盖其他进程尚未读取的文件
你的循环有一个糟糕的设计。首先,你正忙着等待(根本没有睡眠
)文件的出现。其次,当输入存在时,你正在运行4个程序,而不是1个
通过使用inotifywait
监视目录的更改,可以避免繁忙的等待。因此if[[-f$INPUT\u FILE]]
循环体仅在修改目录后运行,而不是以CPU核心可以运行的速度运行
第二个更容易处理:永远不要cat file | something
。如果something
命令行上没有文件名,或者行为不同,则cat
只有在有多个文件要连接时才有用。用于将文件读入Shelll变量,使用foo=$(这很奇怪,可能是一种竞争条件。要隐藏此类错误,您可以将stderr
重定向到/dev/null
-->cat文件2>/dev/null
。此外,您不是说cat文件| grep | awk | awk
。可能一个简单的awk'.'文件就足够了。谢谢您的建议,我已经用c>进行了交流。)在文件| awk-F'[]'/data/{printf”%s“,$3}END{print”“}
Nice!注意cat文件| awk'…'
可以更好地写成awk'…'文件
。你试过添加这样的引号吗?:cat“${INPUT\u file}”
注释:要回复用户,请使用
符号(例如:@SnP)这很奇怪,可能是一种竞争条件。要隐藏此类错误,您可以将stderr
重定向到/dev/null
-->cat文件2>/dev/null
。另外,您不是说cat文件| grep | awk | awk
。可能一个简单的awk'.'文件就足够了。谢谢您的建议,我已经使用ca>进行了交流t file | awk-F'[]'/data/{printf”%s',$3}END{print'}'
Nice!注意cat file | awk'.'
可以更好地写成awk'.''''.
文件。你试过添加这样的引号吗?:cat“${INPUT\u file}”
注释:要回复用户,请使用
符号(例如:@SnP)重写显然是一个实质性的改进,但您可能会注意到,使用cat
不仅仅是;如果您使用grep
直接读取文件,您可以简单地使用-s
来抑制错误消息。感谢Peter提供这些信息,这非常有趣!!但我应该提到我是wo在嵌入式平台上运行rking,其发行版是使用Yocto创建的。inotify tools包目前未包含在文件系统中。由于该包未定义为poky或meta oe层,因此我无法添加它,即使我知道如何添加。此外,您还说,”然后让此脚本将输入文件重命名为其他文件“
”,并在重命名之前检查该文件是否存在“
。如果在[[-f”$input\u file]]之后执行mv
提示错误只会被交换到mv:没有这样的文件或目录
,不是吗?@SnP:如果$INPUT\u File
的另一个使用者正在等待另一个名称,它不会从该脚本中窃取输入文件。不需要重定向mv
的stderr来丢弃错误消息。@SnP:custom build inotifywait用于您的嵌入式平台,或者使用来自perl的inotify系统调用(或者您已经使用的其他语言)
<data>0</data> or <data>1</data> <data>2</data> ..
INPUT_FILE=foo;
inotifywait -m -e close_write -e moved_to --format %f . |
while IFS= read -r event_file;do
[[ $event_file == $INPUT_FILE ]] &&
awk -F '[<,>]' '/data/ {printf "%s ",$3} END {print ""}' "$INPUT_FILE" 2>/dev/null
# echo "$event_file" &&
# date;
done
# tested and working with the commented-out echo/date commands
# Race condition with an asynchronous producer, DON'T USE
while inotifywait -qq -e close_write -e moved_to; do
[[ $event_file == $INPUT_FILE ]] &&
awk -F '[<,>]' '/data/ {printf "%s ",$3} END {print ""}' "$INPUT_FILE" 2>/dev/null
done
#include <unistd.h> // for usleep/dup2
#include <sys/types.h> // for open
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h> // for perror
void waitloop(const char *path)
{
const char *const awk_args[] = { "-F", "[<,>]",
"/data/ {printf \"%s \",$3} END {print \"\"}",
path
};
while(42) {
int fd = open(path, O_RDONLY);
if (-1 != fd) {
// if you fork() here, you can avoid the shell loop too.
dup2(fd, 0); // redirect stdin from fd. In theory should check for error here, too.
close(fd); // and do this in the parent after fork
execv("/usr/bin/awk", (char * const*)awk_args); // execv's prototype doesn't prevent it from modifying the strings?
} else if(errno != ENOENT) {
perror("opening the file");
} // else ignore ENOENT
usleep(10000); // 10 milliseconds.
}
}
// optional TODO: error-check *all* the system calls.