Reputation: 2993
I have bash script which modified file like this
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?
I am new in linux so sorry if my question is too easy but I didn't find any solution.
Thanks!
Upvotes: 18
Views: 31176
Reputation: 6871
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:
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 echo
ing. This is needed to preserve any newlines in the file.
Upvotes: 9
Reputation: 1
I couldn't find a solution but if /etc/postfix/virtual is a soft link and you have permission on the underlying, execute sed on the underlying
$ cat /etc/postfix/virtual
### :-)
hello world
$ ls -lda /etc/postfix/virtual /etc/postfix
dr-xr-xr-x. 2 root root 21 Apr 10 10:39 /etc/postfix
lrwxrwxrwx. 1 root root 27 Apr 10 10:39 /etc/postfix/virtual -> /home/user1/postfix/virtual
$ sed -i "/hello world/d" /etc/postfix/virtual
sed: couldn't open temporary file /etc/postfix/sedmVfrMC: Permission denied
$ sed -i "/hello world/d" /home/user1/postfix/virtual
$ cat /etc/postfix/virtual
### :-)
$ ls -lda /etc/postfix/virtual /etc/postfix
dr-xr-xr-x. 2 root root 21 Apr 10 10:39 /etc/postfix
lrwxrwxrwx. 1 root root 27 Apr 10 10:39 /etc/postfix/virtual -> /home/user1/postfix/virtual
$
Upvotes: 0
Reputation: 61
You could use "sponge" from moreutils.
sed "/hello world/d" /etc/postfix/virtual | sponge /etc/postfix/virtual
Upvotes: 6
Reputation: 2529
Simple custom temp file solution, similar to the solution by @techzilla for those not wanting to use the trap --
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.
Upvotes: 0
Reputation: 1769
AFAIK, you can't configure sed for that. So, you have to run your command with the required privileges.
create a script named, for example, update-postfix (it can have arguments), and put in /usr/local/bin
#!/bin/bash
sed -i "/$1/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 helloworld
instead of the sed command. The update-postfix script is called as the root user.
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).
Upvotes: 1
Reputation: 2835
The file must be modified via temporary file, this is actually what sed was doing but it lacked permissions.
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
Upvotes: 6
Reputation: 785866
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/virtual
is pretty risky.
Upvotes: 2