Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 560
Bhuvan Avatar asked Apr 30 '14 05:04

Bhuvan


People also ask

Can symbolic links be copied?

We can use the -l option of rsync for copying symlinks. rsync copies the symlinks in the source directory as symlinks to the destination directory using this option. Copying the symlinks is successful in this case.

Do Linux symbolic links work on Windows?

Most operating systems offer support for Symbolic Links in one way or another. Linux and Windows both provide support for generic Symbolic Links with some OS exclusive features, i.e. Windows allows for the creation of Junction points which are folder soft links with a little different working.

What happens when you move a symlink?

Once you move a file to which symlink points, symlink is broken aka dangling symlink. You have to delete it and create new one if you want to point to the new filename.


Video Answer


2 Answers

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.

like image 65
Martin Prikryl Avatar answered Sep 25 '22 03:09

Martin Prikryl


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.

like image 20
Xen2050 Avatar answered Sep 24 '22 03:09

Xen2050