bash 需要解释一下 kubectl stdin 和 pipe

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/54032336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 17:05:01  来源:igfitidea点击:

Need some explaination of kubectl stdin and pipe

bashkubernetespipestdinkubectl

提问by Lei Yang

I'm daily user of kubectl, but not expert of linux. Recently I need edit some service type after deployment, so searched and used kubectl replaceand it worked well.

我是 kubectl 的日常用户,但不是 linux 专家。最近我需要在部署后编辑一些服务类型,所以搜索并使用了 kubectl replace并且效果很好。

cat yaml | kubectl replace -f -

service/tracs-pool-1sv replaced

But I don't understand why add a short dash-at the last. The doc only says:

但我不明白为什么在最后添加一个短划线-。文档只说:

Replace a pod based on the JSON passed into stdin.

根据传递到 stdin 的 JSON 替换 pod。

I searched and found thisSO question, and learned kubectl command may be that kind of command that does not read stdin(am I right?).

我搜索并发现了这个SO 问题,并且了解到 kubectl 命令可能是那种不读取标准输入的命令(我说得对吗?)。

I tried

我试过

cat yaml |xargs kubectl replace -f

but error returned:

但错误返回:

the path "apiVersion:" does not exist

So is the ending short dash(-) syntax built for kubectl ONLY? or is some more commonsyntax of linux bash stdin pipe? Can some one explain why xargs not work here and I must place a short dash(-) at the end?

那么结尾的短划线(-)语法是为 kubectl ONLY构建的吗?或者是linux bash stdin 管道的一些更常见的语法?有人可以解释为什么 xargs 在这里不起作用,我必须在最后放一个短划线(-)?

回答by David Maze

This is a reasonably common, but not universal, Un*x convention. (It is mentioned in the POSIX specification and so most non-Linux Unices will support it as well.)

这是一个相当普遍但不普遍的 Un*x 约定。(它在 POSIX 规范中被提及,因此大多数非 Linux Unices 也将支持它。)

The important detail here is that the kubectl ... -foption expects a filename. If you have a file named x.yaml, a more direct way to write what you've shown is just

这里的重要细节是该kubectl ... -f选项需要一个filename。如果您有一个名为 的文件x.yaml,则编写所显示内容的更直接方法就是

kubectl replace -f x.yaml

Where you say -f -, that ostensibly means "a file named -", but kubectl(along with many other tools) actually interprets this to mean "the process's standard input". For instance, you could use this for a very lightweight templating system, like

你所说的-f -,表面上的意思是“一个名为”的文件-,但kubectl(连同许多其他工具)实际上将其解释为“进程的标准输入”。例如,您可以将其用于非常轻量级的模板系统,例如

sed 's/TAG/1.2.3-20190103/g' x.yaml | kubectl replace -f -

For Un*x tooling in general, POSIX.1 statesthat, for many commands,

对于一般的 Un*x 工具,POSIX.1 指出,对于许多命令,

...an operand naming a file can be specified as '-', which means to use the standard input instead of a named file....

...命名文件的操作数可以指定为“-”,这意味着使用标准输入而不是命名文件....

Some commands that support this include cat, grep, sort, and tar (not required by POSIX). One way to move a directory tree between two Linux machines, for instance, is to create a tar file on stdout, pipe that stream via ssh to a remote machine, and then unpack the tar file from stdin:

支持此功能的一些命令包括catgrepsort和 tar (POSIX 不需要)。例如,在两台 Linux 机器之间移动目录树的一种方法是在 stdout 上创建一个 tar 文件,通过 ssh 将该流通过管道传输到远程机器,然后从 stdin 解压该 tar 文件:

tar cf - . | ssh elsewhere tar xf - -C /other/dir

xargsis a tool that converts (most often) a list of filenames on standard input to command line arguments. For instance, find(1) can print a list of matching filenames to its stdout, so you could build a pipeline to delete shell backup files like

xargs是一种将标准输入上的文件名列表(最常见)转换为命令行参数的工具。例如,find(1) 可以将匹配文件名的列表打印到其标准输出,因此您可以构建一个管道来删除 shell 备份文件,例如

find . -name '*~' | xargs rm

You wouldn't usually use this with Kubernetes; your example tries to pass the YAML content itself as command-line arguments to kubectl, for example. You could apply kubectlacross a directory tree with something like

你通常不会在 Kubernetes 中使用它;例如,您的示例尝试将 YAML 内容本身作为命令行参数传递kubectl给 。您可以使用kubectl类似的内容跨目录树应用

find . name '*.yaml' | xargs -n1 kubectl apply -f

but since kubectl ... -falsosupports directory names (not a universal convention) you could do the same thing more directly as

但由于kubectl ... -f支持目录名称(不是通用约定),您可以更直接地做同样的事情

kubectl apply -f . # where . is the current directory