Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 是否可以用POSIX sh(1)复制cat(1)?_Linux_Bash_Shell_Posix_Sh - Fatal编程技术网

Linux 是否可以用POSIX sh(1)复制cat(1)?

Linux 是否可以用POSIX sh(1)复制cat(1)?,linux,bash,shell,posix,sh,Linux,Bash,Shell,Posix,Sh,POSIX sh1能够执行与open2、close2和dup2等等效的各种文件描述符操作,以及从STDIN读取一行 所以我觉得我们可以用一个兼容POSIX的shell脚本来代替cat1,但我还没有拿出一个实际的实现。真的有可能吗?或者,sh1中可能缺少cat1的哪些功能?暂时忘掉GNU扩展吧 别问我为什么要这么做。作为智力测验,也许猫可以将任何文件复制到标准输出;该文件不需要是文本文件。例如,它可能包括NUL,并且NUL不能用sh字符串表示。所以这肯定是cat的一个特性,如果不是不可能的话,也是

POSIX sh1能够执行与open2、close2和dup2等等效的各种文件描述符操作,以及从STDIN读取一行

所以我觉得我们可以用一个兼容POSIX的shell脚本来代替cat1,但我还没有拿出一个实际的实现。真的有可能吗?或者,sh1中可能缺少cat1的哪些功能?暂时忘掉GNU扩展吧

别问我为什么要这么做。作为智力测验,也许猫可以将任何文件复制到标准输出;该文件不需要是文本文件。例如,它可能包括NUL,并且NUL不能用sh字符串表示。所以这肯定是cat的一个特性,如果不是不可能的话,也是非常难以实现的。[注1]

除此之外,您应该能够在while循环中包装一个read和echo,尽管存在一些棘手的问题。例如,准确地复制不以换行符结尾的非空文件

但是,从技术上讲,echo和cat都不是sh的一部分;就像cat一样,它是一个在非Posix系统上可能不存在的实用程序。实际上,没有回声的环境与没有cat的环境的可能性差不多;如果您有sh,那么您可以合理地期望找到标准的命令行实用程序

笔记 最小Posix兼容读取所接受的唯一选项是-r。但是,如果我们有读取的bash实现,我们可以一个字符一个字符地复制文件,即使NUL字符永远不会出现在shell变量中:

while IFS= read -d '' -rn1 char; do
  if [ -z "$char" ]; then printf '\0'; else printf '%s' "$char"; fi
done < "$1" > "$2"
在该调用中读取的完整选项集经过精心设计,以解决bash实现中的各种特性:

IFS=避免从结果中删除尾随空格字符。 -n1导致读取一个字符,直到分隔符。直觉上,-N1更自然,因为-N1忽略了分隔符。但是,read也会从输入中删除NUL字符。由于其目的是在下一个字符是NUL的情况下在$char中存储零个字符,因此我们可以通过使用-n1并将分隔符设置为NUL来避免该问题,因为分隔符检查是在剥离NUL之前完成的。 -d将行分隔符字符设置为NUL。见上文。 -r避免在输入流中被解释;这是集合中唯一与Posix兼容的选项。 不用说,上面的内容只是理论上的兴趣,或者是OP中的智力测验。在实践中,shell脚本只需协调外部实用程序的工作,并且Posix兼容实用程序(如cat、dd、head和tail)的存在就足以满足任何文件复制需求

cat可以将任何文件复制到标准输出;该文件不需要是文本文件。例如,它可能包括NUL,并且NUL不能用sh字符串表示。所以这肯定是cat的一个特性,如果不是不可能的话,也是非常难以实现的。[注1]

除此之外,您应该能够在while循环中包装一个read和echo,尽管存在一些棘手的问题。例如,准确地复制不以换行符结尾的非空文件

但是,从技术上讲,echo和cat都不是sh的一部分;就像cat一样,它是一个在非Posix系统上可能不存在的实用程序。实际上,没有回声的环境与没有cat的环境的可能性差不多;如果您有sh,那么您可以合理地期望找到标准的命令行实用程序

笔记 最小Posix兼容读取所接受的唯一选项是-r。但是,如果我们有读取的bash实现,我们可以一个字符一个字符地复制文件,即使NUL字符永远不会出现在shell变量中:

while IFS= read -d '' -rn1 char; do
  if [ -z "$char" ]; then printf '\0'; else printf '%s' "$char"; fi
done < "$1" > "$2"
在该调用中读取的完整选项集经过精心设计,以解决bash实现中的各种特性:

IFS=避免从结果中删除尾随空格字符。 -n1导致读取一个字符,直到分隔符。直觉上,-N1更自然,因为-N1忽略了分隔符。但是,read也会从输入中删除NUL字符。由于其目的是在下一个字符是NUL的情况下在$char中存储零个字符,因此我们可以通过使用-n1并将分隔符设置为NUL来避免该问题,因为分隔符检查是在剥离NUL之前完成的。 -d将行分隔符字符设置为NUL。见上文。 -r避免在输入流中被解释;这是集合中唯一与Posix兼容的选项。 不用说,上面的内容只是理论上的兴趣,或者是OP中的智力测验。在实践中,shell脚本只应协调外部实用程序的工作,并且Posix兼容实用程序(如cat、dd、head和tail)的存在应该是suf 适合任何文件复制需要


这基本上与@rici的答案相同,但有一个具体的示例,说明不能单独使用sh显示文件

不能单独使用sh复制cat。这是因为sh不提供任何不涉及shell参数的方法将字节从一个文件移动到另一个文件,并且shell参数不能包含空字节

下面是一个简单的例子:

printf 'foo\0bar\n' > tmp.txt  # Create a file containing a null byte
IFS= read -r line < tmp.txt    # Real that line into a variable.
echo "$line"                   # Only outputs "foo"

这基本上与@rici的答案相同,但有一个具体的示例,说明不能单独使用sh显示文件

不能单独使用sh复制cat。这是因为sh不提供任何不涉及shell参数的方法将字节从一个文件移动到另一个文件,并且shell参数不能包含空字节

下面是一个简单的例子:

printf 'foo\0bar\n' > tmp.txt  # Create a file containing a null byte
IFS= read -r line < tmp.txt    # Real that line into a variable.
echo "$line"                   # Only outputs "foo"


对@nodakai来说,更多的是一个问题:这是一个巨大的差异,这就是为什么我要用它来领导。你觉得我需要更明确一点吗?@nodakai:我故意没有提供一个解决方案,但无论如何我添加了更多的词语。可以说,第二段应该是一个评论。@nodakai:我仍然很好奇这个问题的哪个方面引发了你的问题。。。glenn jackman提供的循环(即使有必要的修复)并不复杂,因此一定有一些基本的东西使它成为非解决方案。如果是NULs,那么很酷…@nodakai:如果你的环境在Win32上没有保证,我想,那么它几乎肯定会有cat。从技术上讲,也许我应该把这一点添加到答案中,sh无法模拟cat,或者实际上无法进行任何形式的输出,因为echo几乎没有任何命令保证是内置的;回声很可能是外部的,因此不存在。但这和没有猫的环境一样有意义。我认为你可以合理地抱怨监狱环境缺少这两个方面。现在我想删除我的评论,但我将把它留到历史上。@nodakai:这是一个巨大的不同,这就是为什么我要领导它。你觉得我需要更明确一点吗?@nodakai:我故意没有提供一个解决方案,但无论如何我添加了更多的词语。可以说,第二段应该是一个评论。@nodakai:我仍然很好奇这个问题的哪个方面引发了你的问题。。。glenn jackman提供的循环(即使有必要的修复)并不复杂,因此一定有一些基本的东西使它成为非解决方案。如果是NULs,那么很酷…@nodakai:如果你的环境在Win32上没有保证,我想,那么它几乎肯定会有cat。从技术上讲,也许我应该把这一点添加到答案中,sh无法模拟cat,或者实际上无法进行任何形式的输出,因为echo几乎没有任何命令保证是内置的;回声很可能是外部的,因此不存在。但这和没有猫的环境一样有意义。我认为你可以合理地抱怨监狱环境缺少这两个方面。现在我想删除我的评论,但我会把它留到历史上。这仍然不起作用;它无法区分空行和空字节。尝试用Prtuf的Fo\\0Bar \n\nYea.。NoPE,仍然用空字节替换空白行。从shell的角度来看,空字符串和包含空字节的字符串之间没有区别,因为每个字符串都以空结尾。我并没有说read会错误地处理NULs,只是无法从结果参数中判断是否有。$'\0'和外壳无法区分;两者在遇到第一个NUL之前都包含零个字符。干杯,很好;我从来没有在混音中加入-d。有那么多的东西要找对!这仍然不起作用;它无法区分空行和空字节。尝试用Prtuf的Fo\\0Bar \n\nYea.。NoPE,仍然用空字节替换空白行。从shell的角度来看,空字符串和包含空字节的字符串之间没有区别,因为每个字符串都以空结尾。我并没有说read会错误地处理NULs,只是无法从结果参数中判断是否有。$'\0'和外壳无法区分;两者在遇到第一个NUL之前都包含零个字符。干杯,很好;我从来没有在混音中加入-d。有那么多的东西要找对!