LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware
User Name
Password
Slackware This Forum is for the discussion of Slackware Linux.

Notices


Reply
  Search this Thread
Old 03-23-2019, 09:52 PM   #1
Mechanikx
Member
 
Registered: Jul 2018
Distribution: Slackware
Posts: 351

Rep: Reputation: 258Reputation: 258Reputation: 258
Removing then recreating symlinks with makepkg


I'm learing about making packages in Slackware and to do so I'm playing around with a simple package I've created. If the build tree contains a symlink, it's recommended during the makepkg process to remove the symlinks from the build tree then recreate them during the installation process with a install/doinst.sh

My doinst.sh (created by makepkg) looks like this:

( cd home/mechanikx ; rm -rf linkdata )
( cd home/mechanikx ; ln -sf /home/mechanikx/data linkdata )

At the end of the installation process the first line states that if a symlink by the name of 'linkdata' already exists in my home directory it's removed then the second line states a new 'linkdata' is then created.

I know trying to create a symlink in a directory that already contains a symlink with the same name would cause a failure unless 'ln' was given the 'f' option like it has been above. So I thought the combination of the above two lines were just for good measure. That without specifically the second line it would fail to overwrite the existing 'linkdata' symlink.

But if I leave the 'linkdata' symlink in the build tree and not create a doinst.sh like above, and have a symlink called 'linkdata' that already exists in my home directory it just gets overwritten when I install the package with installpkg. So in either scenario, with a doinst.sh or without and leaving the symlink in the build tree, the end result is the same.

I've googled this and can't find an answer. I have found explanations on what the doinst.sh is for but not why it's necessary to recreate symlinks.

Would someone be able to explain to me why it's recommended to remove the symlinks from the build tree then recreate symlinks with a doinst.sh?

Thanks

Last edited by Mechanikx; 03-23-2019 at 09:54 PM.
 
Old 03-23-2019, 10:29 PM   #2
xor_ebx_ebx
Member
 
Registered: Mar 2019
Location: USA
Distribution: Slackware
Posts: 44

Rep: Reputation: Disabled
Off the top of my head, it's so that packages can be installed to a different location and still function

For example, if there's a symlink in your package that points to /home/mechanikx/data then it will probably always point there, even if you install to /opt or something, which means it will be broken in that scenario. Since the doinst.sh script uses relative paths, symlinks will always point to the right files

It's also convention. We expect the lists in /var/log/packages/ to contain only real files and not symlinks
 
1 members found this post helpful.
Old 03-23-2019, 10:47 PM   #3
volkerdi
Slackware Maintainer
 
Registered: Dec 2002
Location: Minnesota
Distribution: Slackware! :-)
Posts: 2,503

Rep: Reputation: 8461Reputation: 8461Reputation: 8461Reputation: 8461Reputation: 8461Reputation: 8461Reputation: 8461Reputation: 8461Reputation: 8461Reputation: 8461Reputation: 8461
Things get trickier when the symlink is to a directory.
 
2 members found this post helpful.
Old 03-24-2019, 11:34 AM   #4
ehartman
Senior Member
 
Registered: Jul 2007
Location: Delft, The Netherlands
Distribution: Slackware
Posts: 1,674

Rep: Reputation: 888Reputation: 888Reputation: 888Reputation: 888Reputation: 888Reputation: 888Reputation: 888
Quote:
Originally Posted by Mechanikx View Post
( cd home/mechanikx ; rm -rf linkdata )
( cd home/mechanikx ; ln -sf /home/mechanikx/data linkdata )
This syntax is also important for "removepkg", so that it knows which symbolic links have been created when installing this package (as there's no "doremove.sh" in Slackware packages, removepkg has to parse the saved "doinst.sh" instead).
 
1 members found this post helpful.
Old 03-24-2019, 05:19 PM   #5
Mechanikx
Member
 
Registered: Jul 2018
Distribution: Slackware
Posts: 351

Original Poster
Rep: Reputation: 258Reputation: 258Reputation: 258
@xor_ebx_ebx @volkerdi @ehartman, Thank you very much for your responses! It's much appreciated.

Sorry for the late reply but I haven't been able to apply the information you guys have provided me with until this afternoon.

Thanks to your guy's help I think I understand the process:

When I install a package without a doinst.sh and a symlink to a directory there seems to be no difference compared to when there is a doinst.sh as far as installation goes. However there is a difference when I remove the package with 'removepkg'. 'removepkg' doesn't remove the link to the directory, but it will remove a link to a text file, for example.

Which is explained by the output of 'removepkg' (linkbuilds is a symlink to my Slackbuilds directory):

Quote:
WARNING: Unique directory /home/mechanikx/linkbuilds contains new files
WARNING: Unique directory /home/mechanikx contains new files
I understand that when a doinst.sh is included in a package, at the end of the installation it's renamed after the package and stored in /var/log/scripts and then during removal is used, at least in this instance, to remove the symlinks.

If you guys don't mind, I have some follow up questions:

Why are the files in /var/log/scripts executable? I realize that copying an executable will result in another executable. I wouldn't imagine those files are actually executed in their entirety by 'removepkg' because it would defeat the purpose, at least how I understand it.

Why doesn't 'removepkg' deal with symlinks to directories itself? And, why does 'removepkg' give me the second warning above regarding my home directory?

Thanks

Last edited by Mechanikx; 03-24-2019 at 05:20 PM.
 
Old 03-24-2019, 06:01 PM   #6
xor_ebx_ebx
Member
 
Registered: Mar 2019
Location: USA
Distribution: Slackware
Posts: 44

Rep: Reputation: Disabled
Quote:
Originally Posted by Mechanikx View Post
Why are the files in /var/log/scripts executable? I realize that copying an executable will result in another executable. I wouldn't imagine those files are actually executed in their entirety by 'removepkg' because it would defeat the purpose, at least how I understand it
I assume that it's mostly because there would be no point in making them not executable. It would add an extra command (actually, probably more than one) to installpkg that doesn't really accomplish anything

Quote:
Originally Posted by Mechanikx View Post
Why doesn't 'removepkg' deal with symlinks to directories itself? And, why does 'removepkg' give me the second warning above regarding my home directory?
This is because your home directory doesn't appear in any of the other packages installed on your system. Basically, removepkg thinks it should remove your home directory because it's not in any other packages, but stops because it has files in it
 
1 members found this post helpful.
Old 03-24-2019, 07:00 PM   #7
Richard Cranium
Senior Member
 
Registered: Apr 2009
Location: McKinney, Texas
Distribution: Slackware64 15.0
Posts: 3,858

Rep: Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225
Quote:
Originally Posted by Mechanikx View Post
If you guys don't mind, I have some follow up questions:

Why are the files in /var/log/scripts executable? I realize that copying an executable will result in another executable. I wouldn't imagine those files are actually executed in their entirety by 'removepkg' because it would defeat the purpose, at least how I understand it.

Why doesn't 'removepkg' deal with symlinks to directories itself? And, why does 'removepkg' give me the second warning above regarding my home directory?

Thanks
If you don't mind answering, did you look at the scripts themselves before you asked?
 
Old 03-24-2019, 07:32 PM   #8
Mechanikx
Member
 
Registered: Jul 2018
Distribution: Slackware
Posts: 351

Original Poster
Rep: Reputation: 258Reputation: 258Reputation: 258
Quote:
Originally Posted by xor_ebx_ebx View Post
I assume that it's mostly because there would be no point in making them not executable. It would add an extra command (actually, probably more than one) to installpkg that doesn't really accomplish anything
That makes sense. KISS.

Quote:
Originally Posted by xor_ebx_ebx View Post
This is because your home directory doesn't appear in any of the other packages installed on your system. Basically, removepkg thinks it should remove your home directory because it's not in any other packages, but stops because it has files in it
Gotcha Thanks for all your help!
 
Old 03-24-2019, 07:41 PM   #9
Mechanikx
Member
 
Registered: Jul 2018
Distribution: Slackware
Posts: 351

Original Poster
Rep: Reputation: 258Reputation: 258Reputation: 258
Quote:
Originally Posted by Richard Cranium View Post
If you don't mind answering, did you look at the scripts themselves before you asked?
I don't mind at all.

If you mean the scripts in /var/log/scripts, then I only looked at the one pertaining to my package. Since the script contained the commands to remove a symlink then create one I figured that the whole script wouldn't be executed just the removal part. But I didn't want to assume anything so I thought I would seek clarification as to why they're kept executable.

For removepkg itself I have looked at the source code but since I don't have a very good understanding of scripting yet, I couldn't grasp that much. I know the best way to understand what a program is doing is by reading its source code and that is what I plan on doing. I have a shell scripting book that I plan to read over the summer. But sometimes I seem to get ahead of myself.
 
Old 03-24-2019, 10:15 PM   #10
Richard Cranium
Senior Member
 
Registered: Apr 2009
Location: McKinney, Texas
Distribution: Slackware64 15.0
Posts: 3,858

Rep: Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225Reputation: 2225
Quote:
Originally Posted by Mechanikx View Post
I don't mind at all.

If you mean the scripts in /var/log/scripts, then I only looked at the one pertaining to my package. Since the script contained the commands to remove a symlink then create one I figured that the whole script wouldn't be executed just the removal part. But I didn't want to assume anything so I thought I would seek clarification as to why they're kept executable.

For removepkg itself I have looked at the source code but since I don't have a very good understanding of scripting yet, I couldn't grasp that much. I know the best way to understand what a program is doing is by reading its source code and that is what I plan on doing. I have a shell scripting book that I plan to read over the summer. But sometimes I seem to get ahead of myself.
Fair enough. I admit that I did misread the part that I had quoted (the various doinst.sh scripts won't tell you anything anything that's astonishing), thinking that you were talking about makepkg, upgradepkg, et al. (The misreading was all my fault, I should add; the second time I read it, it was perfectly clear what you meant.)

They are actually made executable (code from installpkg):
Code:
  if [ -f $ROOT/install/doinst.sh ]; then
    if [ "$MODE" = "install" ]; then
      echo "Executing install script for $(basename $package)."
    fi
    # If bash is available, use sed to convert the install script to use pushd/popd
    # rather than spawning subshells which is slow on ARM.  This will also speed up
    # install script processing on any platform.
    if [ -x /bin/bash ]; then
      ( cd $ROOT/ ; sed -e's?^( cd \([^;]*\);\(.*\) )$?pushd \1 \&\> /dev/null ; \2 ; popd \&\> /dev/null?g ' install/doinst.sh | /bin/bash ; )
    else
      ( cd $ROOT/ ; sh install/doinst.sh ; )
    fi
  fi 
  # Clean up the mess...
  if [ -d $ROOT/install ]; then
    if [ -r $ROOT/install/doinst.sh ]; then
      cp $ROOT/install/doinst.sh $ADM_DIR/scripts/$shortname
      chmod 755 $ADM_DIR/scripts/$shortname
    fi
    # /install/doinst.sh and /install/slack-* are reserved locations for the package system.
    ( cd $ROOT/install ; rm -f doinst.sh slack-* 1> /dev/null 2>&1 )
    rmdir $ROOT/install 1> /dev/null 2>&1
  fi
TBH, I'd have to step through that sed command to have a clue on what exactly it is doing; however, that line doesn't require the doinst.sh script to be executable.
 
1 members found this post helpful.
Old 03-24-2019, 10:51 PM   #11
Mechanikx
Member
 
Registered: Jul 2018
Distribution: Slackware
Posts: 351

Original Poster
Rep: Reputation: 258Reputation: 258Reputation: 258
Quote:
Originally Posted by Richard Cranium View Post
Fair enough. I admit that I did misread the part that I had quoted (the various doinst.sh scripts won't tell you anything anything that's astonishing), thinking that you were talking about makepkg, upgradepkg, et al. (The misreading was all my fault, I should add; the second time I read it, it was perfectly clear what you meant.)
No worries here

Quote:
Originally Posted by Richard Cranium View Post
They are actually made executable (code from installpkg):
Code:
  if [ -f $ROOT/install/doinst.sh ]; then
    if [ "$MODE" = "install" ]; then
      echo "Executing install script for $(basename $package)."
    fi
    # If bash is available, use sed to convert the install script to use pushd/popd
    # rather than spawning subshells which is slow on ARM.  This will also speed up
    # install script processing on any platform.
    if [ -x /bin/bash ]; then
      ( cd $ROOT/ ; sed -e's?^( cd \([^;]*\);\(.*\) )$?pushd \1 \&\> /dev/null ; \2 ; popd \&\> /dev/null?g ' install/doinst.sh | /bin/bash ; )
    else
      ( cd $ROOT/ ; sh install/doinst.sh ; )
    fi
  fi 
  # Clean up the mess...
  if [ -d $ROOT/install ]; then
    if [ -r $ROOT/install/doinst.sh ]; then
      cp $ROOT/install/doinst.sh $ADM_DIR/scripts/$shortname
      chmod 755 $ADM_DIR/scripts/$shortname
    fi
    # /install/doinst.sh and /install/slack-* are reserved locations for the package system.
    ( cd $ROOT/install ; rm -f doinst.sh slack-* 1> /dev/null 2>&1 )
    rmdir $ROOT/install 1> /dev/null 2>&1
  fi
TBH, I'd have to step through that sed command to have a clue on what exactly it is doing; however, that line doesn't require the doinst.sh script to be executable.
Thank you for this! I'm going to come back to this a little later on when I have more quality time to spend.
 
Old 03-24-2019, 10:55 PM   #12
Mechanikx
Member
 
Registered: Jul 2018
Distribution: Slackware
Posts: 351

Original Poster
Rep: Reputation: 258Reputation: 258Reputation: 258
Thanks again to everyone who has helped me in this thread

I started this on Saturday morning never having made a package and now, Sunday night, I think I have a pretty good overview.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
makepkg produces incorrect symlinks hba Slackware 6 11-14-2015 09:04 AM
[SOLVED] Bug in makepkg and symlinks with blanks in filename? DarkVision Slackware 52 10-01-2015 10:57 PM
recreating previously deleted users box_l SUSE / openSUSE 1 12-10-2004 09:18 AM
Need help making and removing symlinks tigerflag Linux - Hardware 1 04-09-2003 08:23 PM
Recreating boot record/LILO hassles Malibyte Linux - General 2 03-08-2003 11:35 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware

All times are GMT -5. The time now is 06:36 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration