Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
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.
My problem is that I would like to make a shortcut/link/whatever in a Windows directory to point to another windows directory. This shortcut would be accessible from Linux, my Windows partition is mounted on /mnt/win. I don't care if Windows don't recognize the shortcut.
I read a lot of posts about how to create symlinks on Windows and I'm convince that it's not possible for me to create one because my Windows partition is on FAT32 and not NTFS. Hard links don't work for directories and I've seen also that maybe use Cygwin on windows could work but that imply installing new software just for the command ln...
So, if symlink does not work on Windows, can the .lnk file work on Linux? Generally, there's more Linux applications that deal with Windows than the reciprocal (actually I think there's no Windows programs created with compatibility for Linux!). Therefore, I suspect (I hope) there is some utility on Linux to interpret .lnk file and to treat it like a directory, bringing to the referenced directory. Is there such application?
Say we have a link called "crappy.lnk" which points to "X:\Program Files\Crappy-.01\crappy.exe". If you 'strings crappy.lnk|grep -m1 '[A-Z]:\\.'' you should see the path to the item. You'll also note it uses ClippyOS path and drive notation. Since GNU/Linux doesn't need to keep mappings of filesystem mounts and Wintendo "drives" you could mount the drive it's referring to: 'mount /dev/partition /some/mountpoint' and the "mount --bind" it 'mount "/some/mountpoint/Program Files" /mnt/Program_Files'. Now if you read the link like 'strings crappy.lnk|grep -m1 '[A-Z]:\\.' | sed -e "s|\\\|/|g" -e "s| |_|g" -e "s|[A-Z]:|/mnt|g"' it presents a path that makes sense. If that's useful for someone needing access to Playstation-like OS (abbrev.: POS) items I don't know.
When I made the command 'cat crappy.lnk' the output was non-comprehensible. With 'strings' it's clear where the Windows shortcut .lnk points to. With that information it will be possible to make a bash script interpreting any .lnk file.
If you don't mention any program or script that does that I suppose there is no such program. But making a bash script for this won't be difficult and it's better to learn by ourselves!
Thanks a lot!
P.S.: I will maybe post my bash script (if successful) in this thread making a more complete solution to the initial problem. Except there is a section in the forums especially for bash scripting.
But making a bash script for this won't be difficult and it's better to learn by ourselves!
Excellent. That's the spirit.
We've got the Programming forum. While shell scripting != programming most questions about shell scripts usually wind up there which is fine by all of us. OTOH if you decide to ask or post here that's not a problem. I know enough of shell scripting to be a minor nuisance ;-p
BTW, did you notice the "Similar Threads" bar at the bottom of this page? When you read a question it will show other thread titles that may be related.
Actually I prefer reply to my original thread... My english isn't quite good and re-explaining the problem would be again about half an hour of searching for the good words and translation. Although I could refere to this post... But by the way, I remember that on my first post I couldn't submit it if there was a a link.. Anyway, if you say there's no problem .
So I made a little bash script. I comment it a lot to explain what I've done. I don't think that's the more elegant nor general way, but I'm just a newbie after all .
Instead of executing directly the bash script, it's possible to make a new shell function (call it cdw or whatever) in .bash_profile or .bashrc. I think it's a more natural way to do it because the shell script use its own subshell while executing. Otherwise, we have to run the script with ". ./[BASH_SCRIPT].sh" and not only "./[BASH_SCRIPT]".
Sorry for the typos!
Code:
#!/bin/bash
#Interpret Windows shortcuts (.lnk file). Type ". ./[BASH_SCRIPT_NAME].sh [SHORTCUT_NAME].lnk" to be able to
#change directory in the same shell window.
#
WINROOTDIR="C:\\\\"
#Windows root directory. I use it with 'grep' to find the shortcut in the 'strings' command output. It could be a bit more
#convenient to get rid of that variable and use a more precise 'grep' pattern. In that case, I think the best solution
#is to notice that the first output of "strings [SHORTCUT_NAME].lnk" command will always be the drive letter. Retrieving
#this information in a new variable "IdDrive" and replacing "${WINROOTDIR}" by "${IdDrive}" in the "RelPath" assignment
#line should work. I'll give up to you verify that it is indeed the case ;). The four backslashes are a annoyance but
#we have to escape one backslash for 'grep' and one for the path itself. Maybe there is some way to tell grep not to
#interpret those backslashes from the script.
#echo ${WINROOTDIR}
WINMOUNTPOINT="/mnt/win/"
#Linux absolute path where I have mount my Windows partition.
RelPath=`strings "$1" | grep ${WINROOTDIR}[A-Za-z] | tr -d ${WINROOTDIR}`
#Here's where all the work is done. The command 'strings' with argument a Windows .lnk file will display some text
#filtered by 'grep' to keep just the Windows absolute path. After that, 'tr' delete the Windows drive letter.
#echo ${RelPath}
PathFromLinux="${WINMOUNTPOINT}${RelPath}"
#We finally append the relative path of the directory pointed by the shortcut to the absolute path of the Windows
#partition mount point.
#echo "Moving to ${PathFromLinux}"
cd "${PathFromLinux}"
#Do I have to comment that?
I rewrote it a bit if you don't mind. Please note this amount of in-file commenting is definately not my default ;-p
Code:
# If it's gonna be a function it should look like this:
# Note the reserved word "function" isn't necessary in BASH.
function cdw() {
# If the arguments provided are zero the user needs help. Definately.
if [ $# -eq 0 ]; then
# Instead of echoing text you can also use a "here" document.
cat << EOH
${FUNCNAME}: Interpret Windows shortcuts (.lnk file).
Type "${FUNCNAME} /mountpoint/[SHORTCUT_NAME].lnk"
to be able to change directory in the same shell window.
EOH
else
# If the environment variable DEBUG equals 1 we output verbosely and without
# actually cd'ing there. Neat for testing.
[ $DEBUG -eq 1 ] && set -nvx
# The partition where you mounted ClippyOS. I should have used "getopts" do
# accept the user supplying different mountpoints.
WINMOUNTPOINT="/mnt/win"
# If you use UPPERCASE VARIABLE NAMES be consistent using them.
# I like camelCase but that's my problem.
# A Wintendo .lnk also notes the short~1name so we use "-an5" to get only strings
# five chars and over.
RELPATH=`strings -an5 "$1"|grep -m1 '^[A-Z]:\\\[A-Za-z].*'|sed -e 's|\\\|/|g'`
# A Playstation-like OS (aka POS) .lnk file can point to another partition. So if
# the user didn't mount C:\ as $WINMOUNTPOINT it's going nowhere. Let's separate
# the drive letter and ask. It would be more useful to let the user configure things
# himself but that would require sourcing a mapping or using "getopts".
DRV="${RELPATH//:*/}"
echo "Are you sure you mounted drive ${DRV} on ${WINMOUNTPOINT}? [n|y]"; read ANSWER
case answer in y*|Y*)
# Remove drive letter and concat the path.
RELPATH="${RELPATH//*:/}"; FULLPATH="${WINMOUNTPOINT}${RELPATH}"
# The link may have pointed to a non-dir entity. Since I'm tired asking I'll try getting
# the directory it's in once.
[ ! -d "${FULLPATH}" ] && FULLPATH=`dirname "${FULLPATH}"`
# We are five by five, down the pipe!
cd "${FULLPATH}"
;; esac
# be nice, undo debugging.
[ $DEBUG -eq 1 ] && set +nvx
fi
} # End of function cdw (such comments come in nice when your functions
# are pages long or you need to search for them).
You can add the function to your ~/.bashrc (or to a separate file with aliases you source only when needed).
Well that's more like a full-proof highly customizable version!
By the way, I'm using uppercase for constants variables and lowercase for variables that depends on input arguments. I'm more a C++ coder so these habits show through in bash scripting. (this phrase sounds bizarre...)
Unfortunately it didn't work for me... Don't have time to investigate why but it seems after answering yes to the mount point the directory is not changed. Even if I put DEBUG to 0.
The next step for me will be to have the same functionality in a X environment. Having a "follow shortcut" menu option when right-clicking on a .lnk icon in a file browser would be great!
I came across your nice alias/function solution, and adapted it for my Windows machine that runs CygWin. Hopefully this post will be useful to other people.
I simply included this at the end of my .bashrc file:
Code:
# Detailed function to follow Windows-made shortcuts
# Command is 'cdw [SHORTCUT].lnk' with option for DEBUGging - detailed verbifying script, based on environment variable DEBUG=[0|1]
# Adapted from http://www.linuxquestions.org/questions/linux-general-1/follow-windows-shortcuts-from-linux-617917/
# If it's gonna be a function it should look like this:
# Note the reserved word "function" isn't necessary in BASH.
function cdw() {
# If the arguments provided are zero the user needs help. Definitely.
if [ $# -eq 0 ]; then
# Instead of echoing text you can also use a "here" document.
cat << EOH
${FUNCNAME}: Interpret Windows shortcuts (.lnk file).
Type "${FUNCNAME} relative/path/to/[SHORTCUT_NAME].lnk"
to be able to change directory in the same shell window.
EOH
else
# If the environment variable DEBUG equals 1 we output verbosely and without
# actually cd'ing there. Neat for testing.
[ $DEBUG -eq 1 ] && set -nvx
# The map from cygwin to other partitions, for my install is as follows:
cygwinMOUNTPOINT="/cygdrive"
# A Wintendo .lnk also notes the short~1name so we use "-an5" to get only strings five chars and over.
# backticks didn't work for me for some reason, hense command assignments are $()
# I Also have to remove line number from aliased grep output, since my grep is aliased to grep -n
RELPATH=$(strings -an5 "$1"|grep -m1 '^[A-Z]:\\*'| sed -e 's/\\/\//g' | sed -e 's/^[0-9]*://g')
# Separate the drive letter from the path, since my cygwin uses lowercase for partition letters
DRV="${RELPATH//:*/}"
# Remove drive letter and colon from RELPATH
RELPATH=$(echo $RELPATH | sed -e "s/$DRV://g");
# convert drive letter to lowercase for cygwin
DRV=$(echo $DRV | tr '[:upper:]' '[:lower:]')
# concat the path.
FULLPATH="${cygwinMOUNTPOINT}/${DRV}${RELPATH}"
# The link may have pointed to a non-dir entity, such as a shortcut to a program.
# Try getting the directory it's in once so we can cd to that directory.
[ ! -d "${FULLPATH}" ] && FULLPATH=`dirname "${FULLPATH}"`
# We are five by five, down the pipe!
cd "${FULLPATH}"
##;; esac # this didn't work in my install
# be nice, undo debugging.
[ $DEBUG -eq 1 ] && set +nvx
fi
} # End of function cdw (such comments come in nice when your functions
# are pages long or you need to search for them).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.