Copy of /dev/null has different behaviours depending on location - bash

I tried mimicking the behaviour of /dev/null in another location, but some strange error occurs. I learned how to generate a special file similar to /dev/null in -bash: /dev/null: Permission denied.
When in some folder, e.g. home, the following occurs:
$ sudo mknod -m 666 null2 c 1 3
$ cat null2
cat: null2: Permission denied
On the other hand, when in /dev, no error occurs:
$ cd /dev
$ sudo mknod -m 666 null2 c 1 3
$ cat null2
I can reproduce the error on another xubuntu machine, but on a third machine the error does not occur. Any clue whats going on there?
Strangely, on any of these machines, permissions and major/minor are identical:
$ ls -la null2
crw-rw-rw- 1 root root 1, 3 Mär 4 17:42 null2
$ ls -la /dev/null
crw-rw-rw- 1 root root 1, 3 Mär 4 11:46 /dev/null
Also same when copying /dev/null
$ sudo cp -pR /dev/null null2 && cat null2
cat: null2: Permission denied

Is the nodev mount option set for the file system containing your home directory?
Specifying nodev forces the file system to not interpret block special devices (like the null2 special file you create with mknod).

Related

Process substitution not working with sudo

From a main bash script run as root, I want to execute a subprocess using sudo as unpriviledge user nobody; that subprocess should source a file, which content is provided by the main script.
I am trying to solve this using bash process substitution. But I cannot manage to get this to work.
Can someone tell me why the following script, ...
#! /bin/bash
sudo -u nobody \
bash -c 'source /dev/stdin || ls -l /dev/stdin /proc/self/fd/0 /proc/$$/fd/0; echo "A=$A"' \
< <(echo "A=$(ls /root/.profile)")
... when run as root, produces the following ouput ?
root#raspi:~# ./test3.sh
bash: line 1: /dev/stdin: Permission denied
lrwxrwxrwx 1 root root 15 Mar 20 20:55 /dev/stdin -> /proc/self/fd/0
lr-x------ 1 nobody nogroup 64 Aug 21 14:38 /proc/3243/fd/0 -> 'pipe:[79069]'
lr-x------ 1 nobody nogroup 64 Aug 21 14:38 /proc/self/fd/0 -> 'pipe:[79069]'
A=
I would expect reading from stdin to work because, as indicated by ls -l, read access to stdin is granted to nobody (which makes sense).
So why this does not work ? And is there any way to get this to work ?
Answers to this question did not help: as sample above shows, code in the <(...) bloc should access data that only root can.
To see why you have Permission denied, use ls -lL
sudo -u nobody \
bash -c 'source /dev/stdin || ls -lL /dev/stdin /proc/self/fd/0 /proc/$$/fd/0; echo "A=$A"' \
< <(echo "A=$(ls /root/.profile)")
To get around the error, use cat |
sudo -u nobody \
bash -c 'cat | { source /dev/stdin || ls -lL /dev/stdin /proc/self/fd/0 /proc/$$/fd/0; echo "A=$A"; }' \
< <(echo "A=$(ls /root/.profile)")

How to test permission file with bash

Locked for 2 days. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
How do you test permissions on files using bash ? And how does it work ? Does it look for owner's permissions only or all of them (owner, group, others) ? I used -r and -w to test permissions on some files but I got some inaccurate responses.
Here is what I did :
[root#server1 ~]# cat script.sh
#!/bin/bash
FILE="$1"
[ $# -eq 0 ] && exit 1
if [[ -r "$FILE" && -w "$FILE" ]]
then
echo "We can read and write the $FILE"
else
echo "Access denied"
fi
[root#server1 ~]# ll file*
-rw-r--r--. 2 root root 1152 Jun 2 18:24 file1
-rwx------. 1 root root 3 Jun 6 20:35 file2
-r--------. 1 root root 3 Jun 6 20:35 file3
--w-------. 1 root root 3 Jun 6 20:35 file4
---x------. 1 root root 3 Jun 6 20:35 file5
----------. 1 root root 3 Jun 6 20:35 file6
[root#server1 ~]#
[root#server1 ~]# ./script.sh file1
We can read and write the file1
[root#server1 ~]# ./script.sh file2
We can read and write the file2
[root#server1 ~]# ./script.sh file3
We can read and write the file3
[root#server1 ~]# ./script.sh file4
We can read and write the file4
[root#server1 ~]# ./script.sh file5
We can read and write the file5
[root#server1 ~]# ./script.sh file6
We can read and write the file6
Thanks
There is nothing essentially wrong with your script. You are executing it as root so you do have permission to read and write, in fact, root has permission to do anything!
Check this post and you will see that even suppressing the permissions, root user can have access to them. Your output is correct. If you look into the man page of the test command, you can see that the -r and -w flags test if the file exist and in addition permissions to read and write respectively are granted to the user executing the command (both of them since you use a logical and).

Trying to remove my .git folder and 'rm -r .git --force' is not working

rm -r .git
rm -r .git --force
I get the following and there seems to be a never ending supply after I enter 'yes' and move to the next.
override r--r--r-- redacted/staff for .git/objects/95/90087aa4b351e278e6e53ff6240045ab2db6d1?
Analysis and explanation:
The message override r--r--r-- ...? is seen in some versions of the rm command when you try to delete a file or files with the rm command that have write access removed.
To reproduce:
▶ mkdir -p foo/{bar,baz} ; touch foo/bar/qux
▶ chmod -R -w foo
▶ find foo -ls
4305147410 0 dr-xr-xr-x 4 alexharvey wheel 128 24 Mar 18:19 foo
4305147412 0 dr-xr-xr-x 2 alexharvey wheel 64 24 Mar 18:19 foo/baz
4305147411 0 dr-xr-xr-x 3 alexharvey wheel 96 24 Mar 18:19 foo/bar
4305147413 0 -r--r--r-- 1 alexharvey wheel 0 24 Mar 18:19 foo/bar/qux
Now if you try to delete these files you'll be asked if you really want to override this file mode:
▶ rm -r foo
override r-xr-xr-x alexharvey/wheel for foo/baz?
Note also that if you are on Mac OS X or other BSD variant, as appears to be the case, then you have specified the --force argument incorrectly by adding it to the end of the command line, where it will be interpreted as the name of an additional file to delete.
But even if I correct that, -f still can't override r--r--r--. Instead, you would see this:
▶ rm -rf foo
rm: foo/baz: Permission denied
rm: foo/bar/qux: Permission denied
rm: foo/bar: Permission denied
rm: foo: Directory not empty
The fix:
To fix this, firstly restore the write permission within the folder:
▶ chmod -R +w foo
Then rm -r should work fine:
▶ rm -r foo
▶ ls foo
ls: foo: No such file or directory
See also:
this related question at Unix & Linux Stack Exchange.
source code for BSD rm here.
if you want to delete directories in git, just log in to sudo:
$ sudo rm -r file-name
rm -rf .folder
does the trick without spending extra time setting parameters

Is there an elegant way to control permissions for directories created by "install -D"?

I am using [/usr/bin/]install in a Makefile to copy some binaries into my $HOME directory. My umask is set to 700.
The problem is that I am using install -D -m 700 to install the binaries and the parent directory is created with permissions of 755 and not 700:
$ umask
077
$ ls
$ touch hello
$ ls -l
total 0
-rw------- 1 emuso emuso 0 Apr 5 13:15 hello
$ install -D -m 700 hello $PWD/this/is/hello
$ ls -ld this
drwxr-xr-x 3 emuso emuso 4096 Apr 5 13:17 this
$ ls -lR this
this:
total 4
drwxr-xr-x 2 emuso emuso 4096 Apr 5 13:17 is
this/is:
total 0
-rwx------ 1 emuso emuso 0 Apr 5 13:17 hello
I want that the directories this and is get permissions 700 instead of 755.
Solutions that come to my mind are:
using install -d -m 700 to create the directory structure by hand.
using chmod to fix permissions manually.
The major drawback for the first solution is that I have a directory structure, which I would have to travel and create by hand.
So my question is: Is there an elegant way to control permissions for directories created by "install -D"?
What you want to achieve does not seem possible with a single invocation to install only, so you might have to resort to a combination of mkdir and install. Depending on your exact situation, you might be able to take advantage of a canned recipe, using something like this:
define einstall
test -d "$(dir $#)" || mkdir -p "$(dir $#)"
install -m 700 $< $#
endef
some/new/test/hello: hello
$(einstall)
If you plan to play around with canned recipes with make v3.81 or older, please make sure to read this answer to Why GNU Make canned recipe doesn't work?

Redirecting a bash error

I am writing a bash script, which has a problem:
path=$(pwd)
data=$(ls -al $path) > /dev/null 2>/dev/null
The problem occurs if $path is a "locked" directory (no permission for user x), call it "BadDir". In that case, the program outputs:
ls: cannot access /home/user/.../BadDir/..: Permission denied
All I want is to hide this output.
I know there is redirection to /dev/null but I don't know how to use it in this particular case.
you can redirect all error message to another with using EXEC
for test, first create folder
mkdir /tmp/t/
sudo chown root /tmp/t/
sudo chgrp root /tmp/t/
sudo chmod 400 /tmp/t/
e.g:
ls -al /tmp/t/
output:
ls: cannot open directory /tmp/t/: Permission denied
and using EXEC first of file:
exec 2>/dev/null
ls -al /tmp/t/
with exec you can control and redirect all error message or another output

Resources