User avatar
rin67630
Posts: 608
Joined: Fri Mar 04, 2016 10:15 am

Avoiding circular symlinks in an install script

Sun Aug 18, 2019 4:25 am

Hi,
I am writing an install script:

Code: Select all

sudo cp autoreset /usr/bin 
sudo cp avrdude-autoreset /usr/bin 
sudo mv /home/pi/arduino-1.8.8/hardware/tools/avr/bin/avrdude /usr/bin/avrdude-original 
sudo ln -s /usr/bin/avrdude-autoreset /home/pi/arduino-1.8.8/hardware/tools/avr/bin/avrdude
sudo chmod 755 /usr/bin/avrdude-autoreset 
sudo chmod 755 /usr/bin/autoreset
The script is replacing the original program /home/pi/arduino-1.8.8/hardware/tools/avr/bin/avrdude by a symlink.

The problem is that, if you run that script a second time...

Code: Select all

sudo ln -s /usr/bin/avrdude-autoreset /home/pi/arduino-1.8.8/hardware/tools/avr/bin/avrdude
will create a circular symlink and the avr will crash.

Has someone got a clue on how to prevent that?

User avatar
rpdom
Posts: 15592
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 4:52 am

Use a hard link instead of a symlink?

User avatar
rin67630
Posts: 608
Joined: Fri Mar 04, 2016 10:15 am

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 5:03 am

rpdom wrote:
Sun Aug 18, 2019 4:52 am
Use a hard link instead of a symlink?
In the original program? Funny.
Why do you think the whole procedure was done that way?

nigelbartlett1
Posts: 32
Joined: Mon May 06, 2019 9:39 am
Location: London UK

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 7:23 am

First make your script a Bash script by adding, as first line

Code: Select all

#!/bin/bash
Then, prior to creating a symlink, test whether it (doesn’t) exist and create it in that event only

Code: Select all

if [ ! -L linkname ]; then
  sudo ln ...
fi

epoch1970
Posts: 3875
Joined: Thu May 05, 2016 9:33 am
Location: Paris, France

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 7:59 am

rin67630 wrote:
Sun Aug 18, 2019 5:03 am
rpdom wrote:
Sun Aug 18, 2019 4:52 am
Use a hard link instead of a symlink?
In the original program? Funny.
Why do you think the whole procedure was done that way?
Pray tell, what is wrong with hard links? Except they are less notorious than soft links, that is.
"S'il n'y a pas de solution, c'est qu'il n'y a pas de problème." Les Shadoks, J. Rouxel

User avatar
rin67630
Posts: 608
Joined: Fri Mar 04, 2016 10:15 am

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 8:03 am

nigelbartlett1 wrote:
Sun Aug 18, 2019 7:23 am
Then, prior to creating a symlink, test whether it (doesn’t) exist and create it in that event only

Code: Select all

if [ ! -L linkname ]; then
  sudo ln ...
fi
Thank you, that is the approach that I expected.
Could you please give me the concrete example of how to specify the linkname?
The stuff with links (e.g. deleting them) is a bit confusing. Inside a negative if statement, can easily lead to unwanted results if the syntax has an error.
Regards

User avatar
rin67630
Posts: 608
Joined: Fri Mar 04, 2016 10:15 am

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 8:24 am

epoch1970 wrote:
Sun Aug 18, 2019 7:59 am
Pray tell, what is wrong with hard links?
They must be on the same inode, which is not the case.

User avatar
rpdom
Posts: 15592
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 8:40 am

rin67630 wrote:
Sun Aug 18, 2019 5:03 am
rpdom wrote:
Sun Aug 18, 2019 4:52 am
Use a hard link instead of a symlink?
In the original program? Funny.
Why do you think the whole procedure was done that way?
Well, looking at that script I'd say it was because you need to learn more about writing scripts.

epoch1970
Posts: 3875
Joined: Thu May 05, 2016 9:33 am
Location: Paris, France

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 8:44 am

Hard links do not “must”, point to the same inode as the original file, they do by nature.
I don’t see that should be a problem.
Perhaps you meant to say the files are not on the same device, hence you cannot use hard links?
"S'il n'y a pas de solution, c'est qu'il n'y a pas de problème." Les Shadoks, J. Rouxel

User avatar
rin67630
Posts: 608
Joined: Fri Mar 04, 2016 10:15 am

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 9:01 am

epoch1970 wrote:
Sun Aug 18, 2019 8:44 am
Hard links do not “must”, point to the same inode as the original file, they do by nature.
I don’t see that should be a problem.
Perhaps you meant to say the files are not on the same device, hence you cannot use hard links?
No, they are not in the same inode.

User avatar
rpdom
Posts: 15592
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 9:06 am

rin67630 wrote:
Sun Aug 18, 2019 9:01 am
epoch1970 wrote:
Sun Aug 18, 2019 8:44 am
Hard links do not “must”, point to the same inode as the original file, they do by nature.
I don’t see that should be a problem.
Perhaps you meant to say the files are not on the same device, hence you cannot use hard links?
No, they are not in the same inode.
Well, of course different files are not in the same inode. But if you delete one of them and create a hard link then they will be.

User avatar
rin67630
Posts: 608
Joined: Fri Mar 04, 2016 10:15 am

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 9:56 am

rpdom wrote:
Sun Aug 18, 2019 9:06 am
But if you delete one of them and create a hard link then they will be.
The very purpose of the thing is to have the files running in /usr/bin/

Maybe you just could help me to enter the right syntax for the

Code: Select all

if [ ! -L linkname ]
bash statement?

That' s all I need.
Thank you.

User avatar
rin67630
Posts: 608
Joined: Fri Mar 04, 2016 10:15 am

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 10:04 am

rin67630 wrote:
Sun Aug 18, 2019 9:56 am
rpdom wrote:
Sun Aug 18, 2019 9:06 am
But if you delete one of them and create a hard link then they will be.
The very purpose of the thing is to have the files running in /usr/bin/ as an attempt to make this
https://github.com/deanmao/avrdude-rpi
more user friendly

Maybe you just could help me to enter the right syntax for the

Code: Select all

if [ ! -L linkname ]
bash statement?

That' s all I need.
Thank you.

User avatar
PeterO
Posts: 5147
Joined: Sun Jul 22, 2012 4:14 pm

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 10:04 am

rin67630 wrote:
Sun Aug 18, 2019 9:56 am

Maybe you just could help me to enter the right syntax for the

Code: Select all

if [ ! -L linkname ]
bash statement?
The right syntax is

Code: Select all

touch fred
ln -s fred fredLink

linkname="fredLink"
if [ ! -L ${linkname} ]
then 
  echo "Is a link"
fi
See https://www.tldp.org/LDP/abs/html/fto.html
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
rin67630
Posts: 608
Joined: Fri Mar 04, 2016 10:15 am

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 10:14 am

PeterO wrote:
Sun Aug 18, 2019 10:04 am
The right syntax is

Code: Select all

if [ ! -L linkname ]
See https://www.tldp.org/LDP/abs/html/fto.html
Thank you Peter, but my question was not how to use the if statement, but how to specify correctly the symlink within the if statement.
I have seen that you have modified your answer. Thank you...

The original symlink was created with:

Code: Select all

sudo ln -s /usr/bin/avrdude-autoreset /home/pi/arduino-1.8.8/hardware/tools/avr/bin/avrdude
So the corresponding code would be:

Code: Select all

linkname="/home/pi/arduino-1.8.8/hardware/tools/avr/bin/avrdude"

if [ ! -L ${linkname} ]
...
Correct?
Last edited by rin67630 on Sun Aug 18, 2019 10:20 am, edited 1 time in total.

User avatar
PeterO
Posts: 5147
Joined: Sun Jul 22, 2012 4:14 pm

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 10:17 am

rin67630 wrote:
Sun Aug 18, 2019 10:14 am
Thank you Peter, but my question was not how to use the if statement, but how to specify correctly the symlink within the if statement.
You asked
Maybe you just could help me to enter the right syntax for the [command]
Try to ask the right question next time !

But you do it the same as you would specify any other file ! :shock:
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
rin67630
Posts: 608
Joined: Fri Mar 04, 2016 10:15 am

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 10:31 am

PeterO wrote:
Sun Aug 18, 2019 10:17 am
Try to ask the right question next time !
OK Peter, i'll do my best. I probably did initially with :
rin67630 wrote:
Sun Aug 18, 2019 8:03 am
nigelbartlett1 wrote:
Sun Aug 18, 2019 7:23 am
...
if [ ! -L linkname ]; then
sudo ln ...
fi
[/code]
Thank you, that is the approach that I expected.
Could you please give me the concrete example of how to specify the linkname?
The stuff with links (e.g. deleting them) is a bit confusing. Inside a negative if statement, can easily lead to unwanted results if the syntax has an error.
...
But then the discussion drifted and I was too lazy to re-ask the full question.
Regards.

User avatar
PeterO
Posts: 5147
Joined: Sun Jul 22, 2012 4:14 pm

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 10:37 am

rin67630 wrote:
Sun Aug 18, 2019 10:14 am
PeterO wrote:
Sun Aug 18, 2019 10:04 am
The right syntax is

Code: Select all

if [ ! -L linkname ]
See https://www.tldp.org/LDP/abs/html/fto.html
Thank you Peter, but my question was not how to use the if statement, but how to specify correctly the symlink within the if statement.
I have seen that you have modified your answer. Thank you...

The original symlink was created with:

Code: Select all

sudo ln -s /usr/bin/avrdude-autoreset /home/pi/arduino-1.8.8/hardware/tools/avr/bin/avrdude
So the corresponding code would be:

Code: Select all

linkname="/home/pi/arduino-1.8.8/hardware/tools/avr/bin/avrdude"

if [ ! -L ${linkname} ]
...
Correct?
It would be better to define a variable called avrdudeLinkName at the start of the script and set it to the full path.
Then use ${avrdudeLinkName} where ever it is needed. That way the filename only occurs in one place in the script.

DO the same for all the long pathnames.

PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

jahboater
Posts: 4842
Joined: Wed Feb 04, 2015 6:38 pm

Re: Avoiding circular symlinks in an install script

Sun Aug 18, 2019 12:13 pm

This is actually a command called "test"

To see the details of the options, including -L, try

man test

Return to “Advanced users”