bash 如何在linux中为sed命令设置临时文件目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20146239/
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 08:43:15  来源:igfitidea点击:

How to set temp file directory for sed command in linux?

linuxbashsed

提问by Radislav

I have bash script which modified file like this

我有 bash 脚本,它修改了这样的文件

sed -i "/hello world/d" /etc/postfix/virtual

and I ran this script from web application. sed command create temporary file in that directory but user under which web application works doesn't have permissions to create files in that directory. I do not want to give more permissions for the user to that folder. Is it possible to specify temp file location for sed command?

我从网络应用程序运行了这个脚本。sed 命令在该目录中创建临时文件,但 Web 应用程序所在的用户无权在该目录中创建文件。我不想为该文件夹的用户提供更多权限。是否可以为 sed 命令指定临时文件位置?

I am new in linux so sorry if my question is too easy but I didn't find any solution.

我是 linux 新手,很抱歉,如果我的问题太简单了,但我没有找到任何解决方案。

Thanks!

谢谢!

回答by J. M. Becker

The file must be modified via temporary file, this is actually what sed was doing but it lacked permissions.

该文件必须通过临时文件进行修改,这实际上是 sed 正在做的,但它缺乏权限。

When dealing with such a situation, we just do this process manually.

在处理这种情况时,我们只需手动完成此过程。

## TEMP File
TFILE=`mktemp --tmpdir tfile.XXXXX`
trap "rm -f $TFILE" 0 1 2 3 15

##
sed 's_XXX_YYY_' /etc/example > "$TFILE"
cat "$TFILE" > /etc/example

## trap Deletes TFILE on Exit

回答by Harold Zoid

You could use "sponge" from moreutils.

您可以使用moreutils 中的“海绵” 。

sed  "/hello world/d" /etc/postfix/virtual | sponge /etc/postfix/virtual

回答by Pierre-Olivier Vares

AFAIK, you can't configure sed for that. So, you have to run your command with the required privileges.

AFAIK,您不能为此配置 sed。因此,您必须以所需的权限运行您的命令。

  • create a script named, for example, update-postfix (it can have arguments), and put in /usr/local/bin

    #!/bin/bash
    sed -i "//d" /etc/postfix/virtual
    
  • Create a file in /etc/sudoers.d/ (whatever its name, it can be update-postfix or something more generic), replacing _user_with the one calling your script :

    _user_ ALL = (root) NOPASSWD: /usr/local/bin/update-postfix
    

    It allows _user_to run update-postfix (and ony this command) as root

  • In your script, call sudo update-postfix helloworldinstead of the sed command. The update-postfix script is called as the root user.

  • 创建一个脚本,例如,update-postfix(它可以有参数),然后放入 /usr/local/bin

    #!/bin/bash
    sed -i "//d" /etc/postfix/virtual
    
  • 在 /etc/sudoers.d/ 中创建一个文件(不管它的名字是什么,它可以是 update-postfix 或更通用的),用调用你的脚本的人替换_user_

    _user_ ALL = (root) NOPASSWD: /usr/local/bin/update-postfix
    

    它允许_user_root身份运行 update-postfix(以及任何此命令)

  • 在您的脚本中,调用sudo update-postfix helloworld而不是 sed 命令。update-postfix 脚本以 root 用户身份调用。

NB : Called as such, your script (update-postfix) has right to do anything, so be careful what you put in, and sanitize the arguments (what I didn't do here for brevity).

注意:这样调用,你的脚本(更新后缀)有权做任何事情,所以要小心你输入的内容,并清理参数(为了简洁起见,我没有在这里做)。

回答by anubhava

You can always avoid inline editing:

您始终可以避免内联编辑:

sed "/hello world/d" /etc/postfix/virtual > /tmp/_foo

# mv /tmp/_foo /etc/postfix/virtual

But let me caution a web user editing /etc/postfix/virtualis pretty risky.

但是让我警告网络用户编辑/etc/postfix/virtual是非常危险的。

回答by storm_m2138

Simple custom temp file solution, similar to the solution by @techzilla for those not wanting to use the trap --

简单的自定义临时文件解决方案,类似于@techzilla 为那些不想使用陷阱的人提供的解决方案——

sed  "/hello world/d" /etc/postfix/virtual > /tmp/temp_postfix_update && cat /tmp/temp_postfix_update > /etc/postfix/virtual && rm -f /tmp/temp_postfix_update

Per what @EdwinW said, piping the input using cat doesn't remove the file so the write permissions on the file persist.

根据@EdwinW 所说的,使用 cat 管道输入不会删除文件,因此文件的写权限仍然存在。

回答by CenterOrbit

Old question, but I was surprised to find nobody suggesting to use some good-ol' RAM via a variable. Here's what I ended up doing, no need for a temp file at all:

老问题,但我惊讶地发现没有人建议通过变量使用一些好的 RAM。这是我最终做的,根本不需要临时文件:

TEMP_SED=sed "/hello world/d" /etc/postfix/virtual
echo "$TEMP_SED" > /etc/postfix/virtual
unset $TEMP_SED

Note the quotes around the variable when echoing. This is needed to preserve any newlines in the file.

echoing时注意变量周围的引号。这需要保留文件中的任何换行符。