How to copy symbolic link file from Linux to Windows and then back to Linux but still keeping it as a symbolic link

StackOverflow https://stackoverflow.com/questions/23380231

Question

I have a symbolic link in my Linux machine.

I want to copy just the symbolic link (not the target) to a Windows machine and then copy this symbolic link from Windows machine back to some other Linux machine and symbolic link should continue to work.

What I tried:

  1. I gziped the symbolic link
  2. Moved gzipped file to Windows machine using WinSCP
  3. Extracted symbolic link
  4. Moved symbolic file to Linux machine using WinSCP

Now this file is not a symbolic link anymore.

Do anybody knows a trick to do this?

Was it helpful?

Solution

In *nix a symlink is typically just a plain text file with a "symlink" attribute. The file contains the path to the link target. The "symlink" attribute does not exist on Windows. So when you extract the symlink on Windows, it becomes a regular text file [though it may also error, it may depend on a tool you use to extract the archive]. When copied back to *nix, it stays a regular text file.

The only solution would be to keep the "symlink" attribute in some external metadata store and restore the attribute when uploading the file or creating the archive.

Though I'm not aware of any tool that supports this.

You can definitely code this.

  1. Using WinSCP: You make a code that generates WinSCP script. The code would recursively iterate a local directory structure. For a file it will generate the put command to upload it. For a symlink it will generate the ln command to create a symlink. To distinguish the symlink, you can maybe use just a simple heuristics (symlink = a short one-line text file with slashes). A proper way would be to remember the file symlink attribute when extracting the archive (but you would have to code the extraction yourself too then, see also a hint below).

  2. Using archive: I recently implemented this for a ZIP archive. (Even on Windows) You can use the PHP method ZipArchive::setExternalAttributes to flag an archived file as a symlink. Note that the function is available since PHP 5.6 only.

    Sample code:

    $symlink = true; // is symlink?
    $dir = false; // is folder?
    $mode = "755"; // permissions
    
    $local_path = "C:\\zip\\folder\\mylink";
    $zip_path = "folder/mylink";
    
    $attr = 
        (1 << 14) | // this bit seems to be always set
        (1 << ($dir ? 30 : 31)) |
        ($symlink ? (1 << 29) : 0) |
        octdec($mode) << 16;
    
    $zip->addFile($local_path, $zip_path);
    $zip->setExternalAttributesName($zip_path, ZipArchive::OPSYS_UNIX, $attr);
    

    If you are more familiar with Python, see How do I set permissions (attributes) on a file in a ZIP file using Python's zipfile module? It deals with permissions only, but you can easily extend it with the symlink bit, as per my PHP example.

OTHER TIPS

I'd try keeping the link file inside the gzip (or tar.gz) archive, and only extract it on another linux system. I know windows doesn't generally handle linux file attributes & permissions well, and extracting the link on windows probably changes it somehow.

Or it should be easy to recreate the symlink on the new linux system, either in an automated script or just copy & paste your custom ln line into a terminal, like

#!/bin/bash
ln -s TARGET LINKNAME

These are all assuming your new linux system has the same target file in the same place as the original linux system.

I found this thread while trying to get a zipped linux Matlab trial to install. It had no execute bits set and the symlinks for the libraries had become ascii files. It seems that there isn't a command to restore the l bit in file permissions so I wrote this script:

#! /usr/bin/bash
for i in `ls -1 lib*.so*`
do
 # find the broken symlinks
    if file -b --mime-encoding ${i} |grep -q ascii
 # cat the broken link and use it as the ln target
        then ln -sf `cat ${i}` ${i}
    else
        chmod 0755 ${i}
    fi
    done`

1. With VirtualBox

You can use VirtualBox and rsync or extract a tar archive into a Windows host (NTFS) shared folder. However, you need to activate the creation of symbolic links first via

VBoxManage setextradata VM_NAME VBoxInternal2/SharedFoldersEnableSymlinksCreate/SHARE_NAME 1

and your account may not be an administrator account in order to have permissions to create links.

2. With Windows Subsystem for Linux (WSL)

Alternatively, you can use the Windows Subsystem for Linux (WSL) to extract your tar archive to a NTFS partition. It will preserve symbolic links. You can also tar these links again and copy the tar archive to a system you like.

However, so far the WSL is only available on 64-bit editions of Windows 10 and can be activated on Windows 10 Anniversary Update and later. Also note that currently (2018-01-21) the date of files is not restored correctly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top