sudo echo "something" >>/etc/postfix/virtual_alias_maps
Can you help me why the first sudo failed?
On Thu, Nov 21, 2024 at 06:17:31 +0800, Bitfox wrote:
sudo echo "something" >>/etc/postfix/virtual_alias_maps
https://mywiki.wooledge.org/BashPitfalls#pf53
Can you help me why the first sudo failed?
The redirection >> is being done before sudo is executed.
On Wed, Nov 20, 2024 at 9:42 PM Bitfox <hi@bitfox.ddns.net> wrote:
In my bash shell script, when I say:
sudo echo "something" >>/etc/postfix/virtual_alias_maps
it could not run with the prompts:
bin/mask.sh: line 18: /etc/postfix/virtual_alias_maps: Permission
denied
but, if I just say:
echo "something" >>/etc/postfix/virtual_alias_maps
and run that script with the form of "sudo bin/mask.sh", it successes.
Can you help me why the first sudo failed?
Greg gave you the answer.
What I do in this case is, I don't use sudo in the script. Instead I
run the script with sudo like Keith suggested. However, I add this to
the beginning of the script to gracefully exit:
<SNIP>
#!/usr/bin/env bash
# Control our PATH
PATH=/bin:/sbin:/usr/bin:/usr/sbin:$PATH
export PATH
if [[ "${UID}" -ne 0 ]]; then
BTW, what’s the difference between [[ ]] and [ ] here? I know only the latter.
On 20 Nov 2024 17:49 -0500, from greg@wooledge.org (Greg Wooledge):
sudo echo "something" >>/etc/postfix/virtual_alias_maps
Can you help me why the first sudo failed?
The redirection >> is being done before sudo is executed.
Indeed.
The usual pattern if you need to do this in a non-root-only script is
to do something like `echo | sudo tee` to tie the sudo to the thing
that needs write access to the output file.
sudo echo "something" >>/etc/postfix/virtual_alias_maps
Can you help me why the first sudo failed?
The redirection >> is being done before sudo is executed.
On Thu, Nov 21, 2024 at 07:39:33AM CET, Bitfox <hi@bitfox.ddns.net> said:
BTW, what’s the difference between [[ ]] and [ ] here? I know only the latter.
IIRC, [[ ]] is a bash/zsh builtin, [ ] is /bin/[ other name of
/bin/test
On Thu, Nov 21, 2024 at 08:32:30AM +0000, Michael Kjrling wrote:
On 20 Nov 2024 17:49 -0500, from greg@wooledge.org (Greg Wooledge):
sudo echo "something" >>/etc/postfix/virtual_alias_maps
Can you help me why the first sudo failed?
The redirection >> is being done before sudo is executed.
Indeed.
The usual pattern if you need to do this in a non-root-only script is
to do something like `echo | sudo tee` to tie the sudo to the thing
that needs write access to the output file.
My favourite is actually "sudo dd of=<file>" it hasn't the side effect
of flooding your stdout (esp. with a larger, uglier thing).
On Thu, Nov 21, 2024 at 08:14:35 +0100, Erwan David wrote:
On Thu, Nov 21, 2024 at 07:39:33AM CET, Bitfox <hi@bitfox.ddns.net>
said:
BTW, what’s the difference between [[ ]] and [ ] here? I know only the >> > latter.
IIRC, [[ ]] is a bash/zsh builtin, [ ] is /bin/[ other name of
/bin/test
That's partly correct. [[ is a "shell keyword" in bash, meaning it can
be parsed differently. For example, you can put ( ) && || inside it,
which normally wouldn't be allowed. [ is a "shell builtin" in bash,
which means it has the parsing behavior of an ordinary command.
There are /usr/bin/[ and /usr/bin/test commands as well, but you'll
almost never use those. The shell builtin commands take precedence,
unless you disable them, or explicitly type out /usr/bin/[ etc.
The behavior of [ and test is dictated by POSIX, which is a set of
minimal
standards for shell commands (and other things). Shells are free to
add
their own extensions on top of what POSIX requires, and *all* of them
do.
The behavior of [[ is "whatever the shell's developers want it to be",
since it's not a POSIX command at all.
You'll often find that people writing bash script (as opposed to
portable
sh scripts) prefer to use [[ because it handles certain things in a
clearer way, as well as providing additional features. For example,
[[ $a = 1 ]] # You don't need quotes around "$a" here.
[[ $file = *.mp3 ]] # The right hand side of = uses glob
matching.
[[ $file =~ $myregex ]] # =~ does a regular expression (ERE) match.
[[ ( $x -ge 1 ) && ( $y -le 5 ) ]]
The nearest sh equivalents of these would be:
[ "$a" = 1 ]
case $file in *.mp3) ...;; esac
if printf %s "$file" | grep -q -E -- "$myregex"
[ "$x" -ge 1 ] && [ "$y" -le 5 ] # Two separate [ commands.
# DO NOT use [ "$x" -ge 1 -a "$y" -le 5 ]. That's unspecified.
In the specific example code that was posted earliecr in this thread,
the [[ command didn't offer any real advantage over [. However, since
the script was already a bash script, one presumes the author was
simply
following the "use [[ in bash, [ in sh" convention.
On Thu, Nov 21, 2024 at 09:48:06 +0100, tomas@tuxteam.de wrote:
My favourite is actually "sudo dd of=<file>" it hasn't the side effect
of flooding your stdout (esp. with a larger, uglier thing).
Typically you redirect tee's output to /dev/null.
Since the OP wanted to append, "tee -a" is a viable choice, but POSIX dd doesn't have an append option.
Checking my local Debian man pages now, however, I see that Debian's dd
(GNU coreutils) *does* offer an append option.
dd oflag=append conv=notrunc of="$file"
So I guess that's another viable choice, as long as your target system
has GNU coreutils.
Checking my local Debian man pages now, however, I see that Debian's dd
(GNU coreutils) *does* offer an append option.
dd oflag=append conv=notrunc of="$file"
So I guess that's another viable choice, as long as your target system
has GNU coreutils.
On Thu, Nov 21, 2024 at 07:22:53AM -0500, greg@wooledge.org wrote:
On Thu, Nov 21, 2024 at 09:48:06 +0100, tomas@tuxteam.de wrote:
[...]
My favourite is actually "sudo dd of=<file>" it hasn't the side effect
of flooding your stdout (esp. with a larger, uglier thing).
Thanks for all the details :)
Typically you redirect tee's output to /dev/null.
Yes, that's what I always did and what actually motivated me
to search ("there must...").
Since the OP wanted to append, "tee -a" is a viable choice, but POSIX dd
doesn't have an append option.
Good point...
Checking my local Debian man pages now, however, I see that Debian's dd
(GNU coreutils) *does* offer an append option.
dd oflag=append conv=notrunc of="$file"
So I guess that's another viable choice, as long as your target system
has GNU coreutils.
...since the >/dev/null looks less unattractive if you have all that
mouthful for dd. So for append, tee looks neater.
On the third hand, using here "dd" and there "tee" in a script for
the same thing... is not nice either. So if you have a mix of requirements, >yo're busted. Decissions, decissions...
In hindsight, it'd have been nice to give all those "filtering" utils a
"-o" option. Ship, sailed and things :-)
If it helps, "sponge" (in the moreutils package) seems to offer the right interface here:
On Thu, Nov 21, 2024 at 06:44:37PM +0000, Darac Marjal wrote:
[...]
If it helps, "sponge" (in the moreutils package) seems to offer the right interface here:
[...]
Oh, wow -- thanks for that little gem!
On Thu, Nov 21, 2024 at 19:55:04 +0100, tomas@tuxteam.de wrote:
On Thu, Nov 21, 2024 at 06:44:37PM +0000, Darac Marjal wrote:
[...]
If it helps, "sponge" (in the moreutils package) seems to offer the right interface here:
[...]
Oh, wow -- thanks for that little gem!
For the record, sponge -a doesn't actually append to the original
file. As the man page says,
-a
Replace the file with a new file that contains the file's original
content, with the standard input appended to it. This is done
atomically when possible.
hobbit:~$ ls -li y
847514 -rw-r--r-- 1 greg greg 8 Nov 21 07:18 y
hobbit:~$ echo quux | sponge -a y
hobbit:~$ ls -li y
6684744 -rw-r--r-- 1 greg greg 13 Nov 21 14:11 y
The inode number changed, because it's a new file. This may be desirable
or not -- it all depends on your needs. If the file in question is a log file that some program may still be writing to, then this is absolutely
NOT desirable.
On Thu, Nov 21, 2024 at 19:55:04 +0100, tomas@tuxteam.de wrote:
On Thu, Nov 21, 2024 at 06:44:37PM +0000, Darac Marjal wrote:
[...]
If it helps, "sponge" (in the moreutils package) seems to offer the right interface here:
[...]
Oh, wow -- thanks for that little gem!
For the record, sponge -a doesn't actually append to the original
file. As the man page says,
-a
Replace the file with a new file that contains the file's original
content, with the standard input appended to it. This is done
atomically when possible.
hobbit:~$ ls -li y
847514 -rw-r--r-- 1 greg greg 8 Nov 21 07:18 y
hobbit:~$ echo quux | sponge -a y
hobbit:~$ ls -li y
6684744 -rw-r--r-- 1 greg greg 13 Nov 21 14:11 y
The inode number changed, because it's a new file. This may be desirable
or not -- it all depends on your needs. If the file in question is a log file that some program may still be writing to, then this is absolutely
NOT desirable.
Why would you want to append to a file that some other program is also writing to? Sounds messy...
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 546 |
Nodes: | 16 (2 / 14) |
Uptime: | 153:23:54 |
Calls: | 10,383 |
Files: | 14,054 |
Messages: | 6,417,839 |