For example, I have foo.sh with 770 permissions. When I do:
ln -s foo.sh bar.sh
The link bar.sh has 2777 permissions. Why is this? I thought they were meant to be inherited?
The permissions on a symbolic link are largely immaterial. They are normally 777 as modified by the umask setting.
The POSIX standard for symlink() says:
The values of the file mode bits for the created symbolic link are unspecified. All interfaces specified by POSIX.1-2008 shall behave as if the contents of symbolic links can always be read, except that the value of the file mode bits returned in the st_mode field of the stat structure is unspecified.
POSIX provides an lchown() system call; it does not provide an lchmod() function.
(On my MacOS X 10.7.1, with umask 022, a newly created symlink ends up with 755 permissions; with umask 002, the permissions end up as 775. So, the observation that links are created with 770, 700 etc permissions may be accurate; the permissions settings are still immaterial, and do not affect the usability of the symlink.)
Further investigations about symlinks on RHEL 5 and MacOS X
On Linux (RHEL 5 for x86_64; kernel 2.6.18-128.el5), I only get to see 777 permissions on a symlink when it is created:
$ (ls -l xx.pl; umask 777; ln -s xx.pl pqr; ls -l xx.pl pqr)
-rw-r--r-- 1 jleffler rd 319 2011-09-05 22:10 xx.pl
lrwxrwxrwx 1 jleffler rd 5 2011-09-21 10:16 pqr -> xx.pl
-rw-r--r-- 1 jleffler rd 319 2011-09-05 22:10 xx.pl
$
I ran that in a sub-shell so the umask setting was not permanent.
On MacOS X (10.7.1), I get to see variable permissions on a symlink:
$ (ls -l xxx.sql; umask 777; ln -s xxx.sql pqr; ls -l xxx.sql pqr)
-rw-r--r-- 1 jleffler staff 1916 Jun 9 17:15 xxx.sql
ls: pqr: Permission denied
l--------- 1 jleffler staff 7 Sep 21 10:18 pqr
-rw-r--r-- 1 jleffler staff 1916 Jun 9 17:15 xxx.sql
$
Note that this is the same command sequence (give or take the file name) linked to.
On MacOS X, the chmod command has an option -h to change the permissions on a symlink itself:
-h If the file is a symbolic link, change the mode of the link itself rather than the file that the link points to.
On MacOS X, the permissions on the symlink matter; you can't read the symlink unless you have read permission on the symlink (or you're root). Hence the error in the ls output above. And readlink failed. Etc.
On MacOS X, chmod -h 100 pqr (execute) allows me to use the link (cat pqr works) but not to read the link. By contrast, chmod -h 400 pqr allows me to both read the link and use the link. And for completeness, chmod -h 200 pqr allows me to use the link but not to read it. I assume, without having formally tested, the similar rules apply to group and other.
On MacOS X, then, it seems that read or write permission on a symlink allows you to use it normally, but execute permission alone means you cannot find where the link points (readlink(2) fails) even though you can access the file (or, presumably, directory) at the other end of the link.
Conclusion (subject to modification):
On some versions of Linux, you can only get 777 permission on a symlink.
On MacOS X, you can adjust the permissions on a symlink and these affect who can use the symlink.
The MacOS X behaviour is an extension of the behaviour mandated by POSIX - or deviation from the behaviour mandated by POSIX. It complicates life slightly. It means that you have to ensure that anyone who is supposed to use the link has permission to do so. This is normally trivial (umask 022 means that will be the case).
The underlying system call for chown -h on MacOS X is setattrlist(2).
http://en.wikipedia.org/wiki/Symbolic_link
The file system permissions of a symbolic link usually have relevance
only to rename or removal operations of the link itself, not to the
access modes of the target file which are controlled by the target
file's own permissions.
The permissions for the link are just that. What it points to still has it's own permissions.
Related
I deleted a system directory because Carbon Copy Cloner was unable to back it up and suggested replacing it. After deleting and restarting it was rebuilt by the system. However I could not delete the directory from the trash using standard methods or Terminal commands - even logged in as root. Even after disabling System Integrity Protection I had no luck.
Finder says:
The operation can’t be completed because the item “powerlog” is in use.
File was located here:
private>var>db>powerlog>
The directory that was recreated by the system contains subfolders and files but the directory in the trash has none:
sh-3.2# ls -la /Users/admin/Desktop/powerlog
total 0
drwxrwxrwx 3 root wheel 96 Oct 29 16:37 .
drwx------+ 9 admin staff 288 Nov 14 13:18 ..
Attempting rm -R give this result:
sh-3.2# rm -R /Users/admin/.Trash/powerlog
rm: /Users/admin/.Trash/powerlog: Directory not empty
I could not delete it after logging in as root either.
It appears no application is using the folder:
sh-3.2# lsof /Users/admin/.Trash/powerlog
sh-3.2#
I downloaded go1.7.5.darwin-amd64.tar.gz for osx 10.12.2.
Unpacked the tar and went to the /bin directory to see if the Go executable would run.
$ cd Downloads/go/bin
$ ls
total 54560
-rwxr-xr-x# 1 bryanwheelock staff 9884220 Feb 10 16:53 go
-rwxr-xr-x# 1 bryanwheelock staff 15065500 Feb 10 16:53 godoc
-rwxr-xr-x# 1 bryanwheelock staff 2976976 Feb 10 16:53 gofmt
bryanwheelock#Bryans-MacBook Fri Feb 10 16:57:45 ~/Downloads/go/bin
$ go version
-bash: go: command not found
When you type a command without giving the full path, your system will try to find it within all the folders provided in $PATH variable.
In typical Unix environment, your $PATH does not include "your current folder". So you need to either:
call go by its full path (i.e. $HOME/Downloads/go/bin/go); or
call go by its relative path (i.e. ./go); or
put $HOME/Downloads/go/bin in your $PATH variable; or
put . (Unix way of saying "your current folder") in your $PATH; or
put your go binary into folders that already in your $PATH. For example
sudo cp $HOME/Downloads/go/bin/* /usr/local/bin/.
sudo chmod +x go
seems like it does not have execute permission, so just change permission and run it then you should alias your go binary path to your environment to access binary every where.
So I just started getting into using terminal to manage files etc, and I was trying to setup my sublime text shortcut using this line of code:
ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime
However, when I try to do this it says Permission Denied and I have no idea why. I am using a Mac running Mac 10.10.2.
For sublime text 3:
sudo ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/sublime
If you look at the permissions on /usr/local/bin you will see it is owned by root:
$ cd /usr/local
$ ls -l .
total 0
drwxr-xr-x# 8 root wheel 272 Apr 16 11:31 bin
drwxr-xr-x 3 root wheel 102 Apr 16 10:02 include
drwxr-xr-x# 3 root wheel 102 Apr 16 10:19 share
Therefore you need to use sudo to gain super user privileges. You will need to enter your user account password and you will need to be an Admin user (see System Preferences > Users & Groups):
$ sudo ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin
Note that you don't need the trailing subl on the destination as ln will figure that out itself.
If you are on Mac, I would suggest creating a file /usr/local/bin/sublime or somewhere else on your PATH and putting open -a Sublime\ Text $# inside instead of creating a link. open -a tells Mac to open an application that is in your /Applications/ directory. and the $# symbol passes on any additional arguments that you supply to the script. Thus, you can open a file by doing sublime file.ext. That said, it is possible that your permission denial is that you don't have permission for the /usr/local/bin directory. If that is the case, you need to change the permission using chmod, or just put the script somewhere else like ~/bin
In addition, if you're using Sublime Text 3, this is the correct command for the symlink:
ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl
Problem
I have this bash script:
ACTIVE_DB=$(grep -P "^[ \t]*db.active" config.properties | cut -d= -f2 | tr -s " ")
echo $ACTIVE_DB
if [ "$ACTIVE_DB" = "A" ]
then
ln -sf config-b.properties config.properties
else
ln -sf config-a.properties config.properties
fi
config-a.properties
db.active = A
config-b.properties
db.active = B
When I run the script, a hard copy (=cp) is performed and config.properties is often not a symbolic link (nor a physical link for that matter) but a whole new file with the same content as config-a.properties or config-b.properties.
$ ls -li
53 -rw-r--r-- 1 ogregoir ogregoir 582 Sep 30 15:41 config-a.properties
54 -rw-r--r-- 1 ogregoir ogregoir 582 Sep 30 15:41 config-b.properties
56 -rw-r--r-- 1 ogregoir ogregoir 582 Oct 2 11:28 config.properties
When I run this in the prompt manually line by line, I have no trouble and a symbolic link is indeed always created and config.properties points towards config-a.properties or config-b.properties.
$ ls -li
53 -rw-r--r-- 1 ogregoir ogregoir 582 Sep 30 15:41 config-a.properties
54 -rw-r--r-- 1 ogregoir ogregoir 582 Sep 30 15:41 config-b.properties
55 lrwxrwxrwx 1 ogregoir ogregoir 20 Oct 2 11:41 config.properties -> config-b.properties
Notes
No file is open anywhere else (I'm the only active user and the application using the configuration isn't running).
Sometimes ln -sf acts normally, but the usual rule is that it makes a hard copy.
The script is run from another directory, but cds to the directory where the config*.properties files are located before performing the actions here.
The script is way much longer, but this is the shortest example that reproduces the error.
bash version is 4.1.2 (it's local, so I don't care about shellshock).
ln version is 8.4.
Operating System: Red Hat Enterprise Linux Server release 6.5 (Santiago).
Filesystem used for that folder: ext4.
Question
Why doesn't my script consistently create a symbolic link but makes a hard copy?
How to force a symbolic link here?
I suspect you have some other script or code that is overwriting the symlinks. For example, sed -i will trash symlinks. There are a variety of commands and utilities that modify a file by creating a copy, modifying the copy, and then moving the copy over top of the original, which destroys the original symlink.
The only answer possible to the question (as asked): why ln behave as cp is: It can not.
The only other possible answer is: what you present to us is not exactly what is being executed, or there are other scripts running which alter the answer.
Some possible alternatives:
1.- The ln command is actually doing a hard-link. The i-node list (ls -li) confirms that the i-node numbers are distinct. So, no, that is not the reason.
2.- Is there an alias or function for ln?
That is easy to check. Just issue type -a ln inside Bash. The result will show what is bash interpreting ln to be. If it is ONLY the file /bin/ln, then it is correct.
You confirmed that there is no alias or function involved.
3.- As "the script is run from another directory".
The point here is: Is there other file anywhere in the filesystem that has the same i-node number (if ln is actually creating a hard link). The existence of some other file with the same i-node could be verified with (use the inode numbers 53,54,56 from your listing):
find / -follow -inum <your inum>
4.- I hope that you are truly aware that config-b.properties does not actually exist (as a file). Editing such file may trash the link.
Is the actual script executed also changing/updating the file contents?
Note01: Note that the K trick does resolve the extraction in just one external call:
http://www.charlestonsw.com/perl-regular-expression-k-trick/
ACTIVE_DB=$(grep -Po "^[ \t]*db.active[ ]+=[ ]+\K." config.properties)
It has been confirmed that a sed -i to config-b.properties later in the real executed script was the source of the problem.
I'm new to mac with not familiar on terminal command, i put the dvtcolorconvert.rb file on root directory of my volume, this ruby script can converting xcode 3 themes into xcode 4 themes format, which is xxxxxxxx.dvtcolortheme format.
Then run the script /dvtcolorconvert.rb ~/Themes/ObsidianCode.xccolortheme on terminal, but it's always prompt "Permission denied".
what's wrong with this? Anybody can help me solve this problem? Thanks.
Did you give yourself the rights to execute the script?
The following command as super user will do this for you:
sudo chmod 755 'filename'
For details you should read the man page of chmod.
Please read the whole answer before attempting to run with sudo
Try running sudo /dvtcolorconvert.rb ~/Themes/ObsidianCode.xccolortheme
The sudo command executes the commands which follow it with 'superuser' or 'root' privileges. This should allow you to execute almost anything from the command line. That said, DON'T DO THIS! If you are running a script on your computer and don't need it to access core components of your operating system (I'm guessing you're not since you are invoking the script on something inside your home directory (~/)), then it should be running from your home directory, ie:
~/dvtcolorconvert.rb ~/Themes/ObsidianCode.xccolortheme
Move it to ~/ or a sub directory and execute from there. You should never have permission issues there and there wont be a risk of it accessing or modifying anything critical to your OS.
If you are still having problems you can check the permissions on the file by running ls -l while in the same directory as the ruby script. You will get something like this:
$ ls -l
total 13
drwxr-xr-x 4 or019268 Administ 12288 Apr 10 18:14 TestWizard
drwxr-xr-x 4 or019268 Administ 4096 Aug 27 12:41 Wizard.Controls
drwxr-xr-x 5 or019268 Administ 8192 Sep 5 00:03 Wizard.UI
-rw-r--r-- 1 or019268 Administ 1375 Sep 5 00:03 readme.txt
You will notice that the readme.txt file says -rw-r--r-- on the left. This shows the permissions for that file. The 9 characters from the right can be split into groups of 3 characters of 'rwx' (read, write, execute). If I want to add execute rights to this file I would execute chmod 755 readme.txt and that permissions portion would become rwxr-xr-x. I can now execute this file if I want to by running ./readme.txt (./ tells the bash to look in the current directory for the intended command rather that search the $PATH variable).
schluchc alludes to looking at the man page for chmod, do this by running man chmod. This is the best way to get documentation on a given command, man <command>
In my case, I had made a stupid typo in the shebang.
So in case someone else on with fat fingers stumbles across this question:
Whoops: #!/usr/local/bin ruby
I meant to write: #!/usr/bin/env ruby
The vague error ZSH gives sent me down the wrong path:
ZSH: zsh: permission denied: ./foo.rb
Bash: bash: ./foo.rb: /usr/local/bin: bad interpreter: Permission denied
You should run the script as 'superuser', just add 'sudo' in front of the command and type your password when prompted.
So try:
sudo /dvtcolorconvert.rb ~/Themes/ObsidianCode.xccolortheme
If this doesn't work, try adapting the permissions:
sudo chmod 755 /dvtcolorconvert.rb
sudo chmod 755 ~/Themes/ObsidianCode.xccolortheme
To run in the administrator mode in mac
sudo su
use source before file name,,
like my file which i want to run from terminal is ./jay/bin/activate
so i used command "source ./jay/bin/activate"
Check the permissions on your Ruby script (may not have execute permission), your theme file and directory (in case it can't read the theme or tries to create other themes in there), and the directory you're in when you run the script (in case it makes temporary files in the current directory rather then /tmp).
Any one of them could be causing you grief.