println

package main
import “fmt”
func main() {
defer println(“defer 1”)
defer func() {
fmt.Println(“defer2.1”)
println(“defer2”)
}()
defer println(“defer3”)
}



输出:
defer2.1
defer3
defer2
defer 1
原因:
println 是把结果输出到 standard error
fmt.Println 是把结果输出到 standard output



因为打开的是两个文件描述符。所以最终输出顺序不固定,争抢文件描述符的锁。

println is an built-in function (into the runtime) which may eventually be removed, while the fmt package is in the standard library, which will persist.



Current implementations provide several built-in functions useful during bootstrapping. These functions are documented for completeness but are not guaranteed to stay in the language. They do not return a result.



Function Behavior



print prints all arguments; formatting of arguments is implementation-specific
println like print but prints spaces between arguments and a newline at the end
Thus, they are useful to developers, because they lack dependencies (being built into the compiler), but not in production code. It also important to note that print and println report to stderr, not stdout.



The family provided by fmt, however, are built to be in production code. They report predictably to stdout, unless otherwise specified. They are more versatile (fmt.Fprint* can report to any io.Writer, such as os.Stdout, os.Stderr, or even a net.Conn type.) and are not implementation specific.



Most packages that are responsible for output have fmt as a dependency, such as log. If your program is going to be outputting anything in production, fmt is most likely the package that you want.



int main(){
fprintf(stdout,”Hello “);
fprintf(stderr,”World!”);
return0;
}



解答:这段代码的输出是什么呢?
World!Hello



这是为什么呢?在默认情况下,stdout是行缓冲的,他的输出会放在一个buffer里面,只有到换行的时候,才会输出到屏幕。而stderr是无缓冲的,会直接输出,举例来说就是printf(stdout, “xxxx”) 和 printf(stdout, “xxxx\n”),前者会憋住,直到遇到新行才会一起输出。而printf(stderr, “xxxxx”),不管有么有\n,都输出。



fprintf(stderr, “Can’t open it!\n”);
fprintf(stdout, “Can’t open it!\n”);
printf(“Can’t open it!\n”);
这3句效果不是一样啊,有什么区别吗
stdout – 标准输出设备 (printf(“..”)) 同 stdout。
stderr – 标准错误输出设备
两者默认向屏幕输出。
但如果用转向标准输出到磁盘文件,则可看出两者区别。stdout输出到磁盘文件,stderr在屏幕。
my.exe > tmp.txt
Can’t open it!



stdout 主要处理的是使用者输出
stderr 主要处理的错误信息输出
相比stdout, stderr没有缓冲设置
将”正常输出”和”错误信息输出”加以分离,可以让程序以不同的方式对待两种不同的输出,例如可以将错误信息显示在控制台上,而正常输出重新定向到某个文件上。



tee命令文件过滤分割与合并
tee命令用于将数据重定向到文件,另一方面还可以提供一份重定向数据的副本作为后续命令的stdin。简单的说就是把数据重定向到给定文件和屏幕上。



存在缓存机制,每1024个字节将输出一次。若从管道接收输入数据,应该是缓冲区满,才将数据转存到指定的文件中。若文件内容不到1024个字节,则接收完从标准输入设备读入的数据后,将刷新一次缓冲区,并转存数据到指定文件。



语法
tee(选项)(参数)
选项
-a:向文件中重定向时使用追加模式;
-i:忽略中断(interrupt)信号。
参数
文件:指定输出重定向的文件。



在终端打印stdout同时重定向到文件中:



ls | tee out.txt | cat -n
1 1.sh
2 1.txt



/dev/null :代表空设备文件



 :代表重定向到哪里,例如:echo “123” > /home/123.txt
1  :表示stdout标准输出,系统默认值是1,所以”>/dev/null”等同于”1>/dev/null”
2  :表示stderr标准错误
&  :表示等同于的意思,2>&1,表示2的输出重定向等同于1




1 > /dev/null 2>&1 语句含义:
1 > /dev/null : 首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。
2>&1 :接着,标准错误输出重定向(等同于)标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。



实例解析:



cmd >a 2>a 和 cmd >a 2>&1 为什么不同?
cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件会被打开两遍,由此导致stdout和stderr互相覆盖。
cmd >a 2>&1 :stdout直接送往文件a ,stderr是继承了FD1的管道之后,再被送往文件a 。a文件只被打开一遍,就是FD1将其打开。



两者的不同点在于:



cmd >a 2>a 相当于使用了FD1、FD2两个互相竞争使用文件 a 的管道;
cmd >a 2>&1 只使用了一个管道FD1,但已经包括了stdout和stderr。
从IO效率上来讲,cmd >a 2>&1的效率更高。



将stderr stdout 分开:
{ { echo stdout; echo stderr >&2; } > >(tee stdout.txt); } 2> >(tee stderr.txt)



Category golang