UNIX / Linux / Mac OSX get permission of file as number - macos

This must be really simple to do but have completely drawn a blank. I can see the permission of files by using ls -la which can give something like:
-rwxr-xr-x 1 james staff 68 8 Feb 13:33 basic.sh*
-rw-r--r-- 1 james staff 68 8 Feb 13:33 otherFile.sh*
How do I translate that into a number for use with chmod like chmod 755 otherFile.sh (with out doing the manual conversion).

stat -f "%Lp" [filename] works for me in OS X 10.8.

You should be able to use the stat command instead of ls. From looking at the manpage, this should work to get the file permissions:
for f in dir/*
do
perms=$(stat -f '0%Hp%Mp%Lp' $f)
echo "$f has permissions $perms"
done
(although I am not at my Mac at the moment and therefore cannot test it).

Related

How to sync the modification date of folders within two directories that are the same?

I have a Dropbox folder on one computer with all the original modification dates. Recently, after transferring my data onto another computer, due to a .DS_Store issue, some of the folder's "Date Modified" dates were changed to today. I am trying to write a script that would take the original modification date of a folder, and then be able to find the corresponding folder in my new computer, and change it using touch. The idea is to use stat and touch -mt to do this. Does anyone have any suggestions or better thoughts? Thanks.
Use one folder as the reference for another with --reference=SOURCE:
$ cd "$(mktemp --directory)"
$ touch -m -t 200112311259 ./first
$ touch -m -t 200201010000 ./second
$ ls -l | sed "s/${USER}/user/g"
total 0
-rw-r--r-- 1 user user 0 Dec 31 2001 first
-rw-r--r-- 1 user user 0 Jan 1 2002 second
$ touch -m --reference=./first ./second
$ ls -l | sed "s/${USER}/user/g"
total 0
-rw-r--r-- 1 user user 0 Dec 31 2001 first
-rw-r--r-- 1 user user 0 Dec 31 2001 second

Wrong owner upon file creation in particular directory

I'm facing #subj . If I try to create a file/dir in my home directory it gets created as root:daemon instead of user:staff. I found this behaviour only for one directory ( all the other dirs aren't affected).
It used to create files properly before and now it sets root:daemon with 644.
I can't see any guid or sticky bits, etc.
What do I miss?
$ whoami
user
$ pwd
/home/user
$ touch 1
$ ll 1
-rw-r--r-- 1 root daemon 0 Jul 31 09:50 1
$ ls -ld /home/user/
drwxr-xr-x 13 user staff 4096 Jul 31 09:50 /home/user/
$ ls -ld /home/
drwxr-xr-x 5778 root staff 450560 Jul 31 08:21 /home/
$ umask
0022
I might be due to file access control set to root:daemon. If you run
getfacl /home/user
it should tell you if that was the problem. If yes, then you can set per-folder with the command setfacl with the parameters you prefer.
Another cause that comes to my mind is if that is a mountpoint masked with those particular user and group; you can check that with cat /etc/fstab.

Some relative paths on macOS 10.15 Catalina beta (19A471t) do not work

There's an odd behaviour when using relative paths. For example:
$ cd /Users
$ ls -l ../bin
ls: ../bin: No such file or directory
$ ls -l /bin
-r-xr-xr-x 1 root wheel 623344 31 May 08:33 bash
-rwxr-xr-x 1 root wheel 36768 31 May 08:33 cat
...
But the following works fine:
$ cd /dev
$ ls -l ../bin
-r-xr-xr-x 1 root wheel 623344 31 May 08:33 bash
-rwxr-xr-x 1 root wheel 36768 31 May 08:33 cat
...
Some other directories do not return the No such file or directory message, but they act as if there was nothing there. For example:
$ cd /Users
$ ls -l ../dev
$
returns nothing, and back to the prompt. The following, however, works fine:
$ cd /bin
$ ls -l ../dev
crw------- 1 root wheel 19, 1 11 Jun 16:54 afsc_type5
crw------- 1 root wheel 10, 0 11 Jun 16:54 auditpipe
crw-r--r-- 1 root wheel 9, 3 11 Jun 16:54 auditsessions
...
I could not find anything on the release notes. The WWDC2019 session 710 (What's New in Apple File Systems) also does not mention anything.
I think it might be related to the new separation of directories into a read-only and a read-write volumes. But still, it should work.
I found this to be specially problematic when using npm link, which links to /usr/local/lib/node_modules/... but expressed as a relative path from the destination package. After linking I have to manually change the link from relative to absolute. An ugly hack that may have some unforeseen consequences.
Anybody any clues?
The issue has been resolved with in Catalina beta 4.

How to follow symlinks for which output?

I have this handy function for showing symlinks from the which command.
function whichl() {
ls -la $(which -a $#)
}
It works great for things that are symlinked from the path, like python.
$ whichl python
-rwxr-xr-x 1 root wheel 66880 Mar 27 23:02 /usr/bin/python
lrwxr-xr-x 1 me admin 43 Dec 19 2017 /usr/local/bin/python -> /usr/local/Cellar/python/2.7.14/bin/python2
$ ls -la $(which -a python3)
lrwxr-xr-x 1 me admin 34 Jun 8 10:42 /usr/local/bin/python3 -> ../Cellar/python/3.6.5/bin/python3
It does not work so great when which doesn't find anything; the ls -la command runs against the current directory. This has confused me for the last time!
So, looking for two answers here.
Is there a better way to get which results to show symlinks?
I'm on OS X (if it wasn't obvious) and man which says my version is BSD December 13, 2006.
What is the best way to get my helper function to halt on when which returns no results? I've confirmed the return code in this case is 1, but a simple set -e doesn't change the behavior.
As I mentioned in the question, this doesn't work:
function whichl() {
set -e
ls -la $(which -a $#)
}
The explanation from the comments:
You call set -e in the current shell (where the function runs) but which is executed in a subshell (because of $(...)). You can store the value produced by $(which -a $#) in a variable and run ls -la only when it is not empty.
Following that suggestion, this is what I arrived at.
function whichl() {
RESULT=$(which -a $#)
if [ -z "$RESULT" ]; then
echo "No results for \"$#\""
return 1
fi
ls -la -- ${RESULT}
}
And it works perfectly from all I can test right now!
$ whichl python python3
-rwxr-xr-x 1 root wheel 66880 Mar 27 23:02 /usr/bin/python
lrwxr-xr-x 1 me admin 43 Dec 19 2017 /usr/local/bin/python -> /usr/local/Cellar/python/2.7.14/bin/python2
lrwxr-xr-x 1 me admin 34 Jun 8 10:42 /usr/local/bin/python3 -> ../Cellar/python/3.6.5/bin/python3
Notice it returns 3 results from 2 inputs, the system python and brew python.
$ whichl foo bar
No results for "foo bar"

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?

Resources