[SOLVED] Removing then recreating symlinks with makepkg
SlackwareThis Forum is for the discussion of Slackware Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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?
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
( 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).
@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?
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
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
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?
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
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
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.
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.
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
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.