fly*_*ire 1440 linux bash redirect pipe stream
要将stdout重定向到Bash中的截断文件,我知道要使用:
cmd > file.txt
Run Code Online (Sandbox Code Playgroud)
要在Bash中重定向stdout,追加到文件,我知道要使用:
cmd >> file.txt
Run Code Online (Sandbox Code Playgroud)
要将stdout和stderr重定向到截断的文件,我知道要使用:
cmd &> file.txt
Run Code Online (Sandbox Code Playgroud)
如何重定向附加到文件的stdout和stderr?cmd &>> file.txt不适合我.
Ale*_*lli 1881
cmd >>file.txt 2>&1
Run Code Online (Sandbox Code Playgroud)
Bash从左到右执行重定向,如下所示:
>>file.txt:file.txt在追加模式下打开并重定向stdout.2>&1:重定向stderr到" stdout当前的位置".在这种情况下,这是一个以追加模式打开的文件.换句话说,&1重用stdout当前使用的文件描述符.The*_*sai 348
有两种方法可以执行此操作,具体取决于您的Bash版本.
经典和便携(Bash pre-4)方式是:
cmd >> outfile 2>&1
Run Code Online (Sandbox Code Playgroud)
非便携的方式,开始猛砸4是
cmd &>> outfile
Run Code Online (Sandbox Code Playgroud)
(比喻&> outfile)
为了良好的编码风格,你应该
如果您的脚本已经开始#!/bin/sh(无论是否有意),那么Bash 4解决方案以及通常任何特定于Bash的代码都不是可行的方法.
还要记住Bash 4 &>>只是更短的语法 - 它不会引入任何新功能或类似的东西.
这里描述的语法是(除了其他重定向语法之外):http://bash-hackers.org/wiki/doku.php/syntax/redirection#appending_redirected_output_and_error_output
Aar*_* R. 87
在Bash中,您还可以明确指定重定向到不同的文件:
cmd >log.out 2>log_error.out
Run Code Online (Sandbox Code Playgroud)
附加将是:
cmd >>log.out 2>>log_error.out
Run Code Online (Sandbox Code Playgroud)
A B*_*A B 63
在Bash 4(以及ZSH 4.3.11)中:
cmd &>>outfile
Run Code Online (Sandbox Code Playgroud)
刚开箱即用
Pra*_*ami 50
这应该工作正常:
your_command 2>&1 | tee -a file.txt
Run Code Online (Sandbox Code Playgroud)
它会将所有日志存储在file.txt中,并将它们转储到终端上.
Qui*_*hou 24
试试这个
You_command 1>output.log 2>&1
Run Code Online (Sandbox Code Playgroud)
您对&> x.file的使用在bash4中有效.对不起:(
0,1,2 ... 9是bash中的文件描述符.
0代表stdin,1代表stdout,2代表stderror.任何其他临时使用都可以使用3~9.
可以使用operator >或>>(append)将任何文件描述符重定向到其他文件描述符或文件.
用法:< 类file_descriptor > > < 文件名 | &file_descriptor >
请参阅http://www.tldp.org/LDP/abs/html/io-redirection.html
F. *_*uri 20
来自“ 2>&1 ”是什么意思?,我将在这个答案中使用命令:
ls -ld /tmp /tnt
Run Code Online (Sandbox Code Playgroud)
用于同时填充STDIN和STDERR。(希望您的root中没有任何名为 的条目。)tnt
您可以从脚本本身计划重定向:
ls -ld /tmp /tnt
Run Code Online (Sandbox Code Playgroud)
运行此命令将创建/追加logfile.txt,包含:
#!/bin/bash
exec 1>>logfile.txt
exec 2>&1
/bin/ls -ld /tmp /tnt
Run Code Online (Sandbox Code Playgroud)
或者
/bin/ls: cannot access '/tnt': No such file or directory
drwxrwxrwt 2 root root 4096 Apr 5 11:20 /tmp
Run Code Online (Sandbox Code Playgroud)
创建或附加标准输出到logfile.txt以及创建或附加错误输出到errfile.txt.
您可以创建两个不同的日志文件,附加到一个整体日志并重新创建另一个最后的日志:
#!/bin/bash
exec 1>>logfile.txt
exec 2>>errfile.txt
/bin/ls -ld /tmp /tnt
Run Code Online (Sandbox Code Playgroud)
运行这个脚本将会
lastlog.txt已经存在,则将它们重命名为lastlog.old(lastlog.old如果存在则覆盖)。lastlog.txt。overall.log#!/bin/bash
if [ -e lastlog.txt ] ;then
mv -f lastlog.txt lastlog.old
fi
exec 1> >(tee -a overall.log /dev/tty >lastlog.txt)
exec 2>&1
ls -ld /tnt /tmp
Run Code Online (Sandbox Code Playgroud)
所以你有了
lastlog.txt上次运行日志文件lasterr.txt上次运行错误文件lastlog.old之前的运行日志文件lasterr.old上次运行错误文件overall.log附加整体日志文件overall.err附加总体错误文件combined.log附加总体错误和日志组合文件。#!/bin/bash
[ -e lastlog.txt ] && mv -f lastlog.txt lastlog.old
[ -e lasterr.txt ] && mv -f lasterr.txt lasterr.old
exec 1> >(tee -a overall.log combined.log /dev/tty >lastlog.txt)
exec 2> >(tee -a overall.err combined.log /dev/tty >lasterr.txt)
ls -ld /tnt /tmp
Run Code Online (Sandbox Code Playgroud)
$sTime为了确保两个文件将呈现完全相同的时间戳。(如果$EPOCHSECONDS调用两次,则每次扩展之间的它们可能会有所不同!)$$以确保唯一性。第三次运行后,您必须找到 9 个文件:
ls -ltr
-rw-r--r-- 1 user user 49 19 nov 10:36 log-20231119103611-00120649.txt
-rw-r--r-- 1 user user 73 19 nov 10:36 err-20231119103611-00120649.txt
-rw-r--r-- 1 user user 73 19 nov 10:36 err-20231119103634-001207b8.txt
-rw-r--r-- 1 user user 49 19 nov 10:36 log-20231119103634-001207b8.txt
-rw-r--r-- 1 user user 147 19 nov 10:40 overall.log
-rw-r--r-- 1 user user 219 19 nov 10:40 overall.err
-rw-r--r-- 1 user user 49 19 nov 10:40 log-20231119104000-001216f0.txt
-rw-r--r-- 1 user user 73 19 nov 10:40 err-20231119104000-001216f0.txt
-rw-r--r-- 1 user user 366 19 nov 10:40 combined.log
Run Code Online (Sandbox Code Playgroud)
stdbuf:对于Fonic的评论,经过一番测试,我不得不同意:用tee,stdbuf是没用的。但 ...
# Source this to multi-log your session
[ -e lasterr.txt ] && mv -f lasterr.txt lasterr.old
[ -e lastlog.txt ] && mv -f lastlog.txt lastlog.old
exec 2> >(exec stdbuf -i0 -o0 tee -a overall.err combined.log /dev/tty >lasterr.txt)
exec 1> >(exec stdbuf -i0 -o0 tee -a overall.log combined.log /dev/tty >lastlog.txt)
Run Code Online (Sandbox Code Playgroud)
一旦找到了这个,你可以尝试:
ls -ld /tnt /tmp
Run Code Online (Sandbox Code Playgroud)
来自我关于如何将 Unix 时间戳转换为日期字符串的3 条评论
我使用了更复杂的命令来实时squid解析和重新组装日志:由于每行都以毫秒为单位的UNIX EPOCH开头,我在第一个点上分割该行,在EPOCH SECONDS之前添加符号以将它们传递给然后重新组装输出和行的其余部分使用点。@date -f - +%F\ %Tdatepaste -d .
exec {datesfd}<> <(:)
tail -f /var/log/squid/access.log |
tee >(
exec sed -u 's/^\([0-9]\+\)\..*/@\1/'|
stdbuf -o0 date -f - +%F\ %T >&$datesfd
) |
sed -u 's/^[0-9]\+\.//' |
paste -d . /dev/fd/$datesfd -
Run Code Online (Sandbox Code Playgroud)
与date,stdbuf被要求...
exec关于和命令的一些解释stdbuf:forks通过使用或$(...)运行subshell<(...)来完成,它将在另一个子shell ( subsubshel l ) 中执行二进制文件。该命令告诉 shell 脚本中没有更多命令要运行,因此二进制( ) 将作为替换进程在同一级别执行(无需保留更多内存来运行另一个子进程)。execstdbuf ... tee
来自bash的手册页 ( man -P'less +/^\ *exec\ ' bash):
Run Code Online (Sandbox Code Playgroud)exec [-cl] [-a name] [command [arguments]] If command is specified, it replaces the shell. No new process is created....
这并不是真正需要的,但可以减少系统占用空间。
来自stdbuf的手册页:
Run Code Online (Sandbox Code Playgroud)NAME stdbuf - Run COMMAND, with modified buffering operations for its standard streams.
这将告诉系统使用无缓冲 I/O 来执行tee命令。因此,当出现一些输入时,所有输出都将立即更新。
令我惊讶的是,近十年来,还没有人发布这种方法:
如果使用的bash较旧版本&>>不可用,您还可以执行以下操作:
(cmd 2>&1) >> file.txt
Run Code Online (Sandbox Code Playgroud)
这产生了一个subshell,因此它的效率不如的传统方法高cmd >> file.txt 2>&1,但这种方法对我来说更自然,更容易理解:
此外,括号消除了任何歧义的顺序,尤其是如果您想将stdout和stderr用管道传递给另一个命令时,尤其如此。
| 归档时间: |
|
| 查看次数: |
702155 次 |
| 最近记录: |