Crie uma árvore de links simbólicos em diretórios existentes

5

Eu carrego toda a minha música em um drive USB de 1TB e tenho uma regra do udev para linkar simbolicamente para $HOME/Music/ quando eu conecto a um dos meus laptops, o que ele faz.

O problema que tenho é que isso funciona bem onde o diretório não existe no laptop, mas não cria a árvore de requisitos onde existe um diretório pré-existente com o mesmo nome (Artist / Album / *. Flac) no laptop.

O script que eu executo atualmente é o seguinte:

#!/usr/bin/env bash
# repopulate music links when drive plugged in

shopt -s nullglob
export DISPLAY=:0
export XAUTHORITY=/home/jason/.Xauthority

music=(/media/Apollo/Music/*)

find /home/jason/Music -type l -exec rm {} \;
for dirs in "${music[@]}"; do
  ln -s "$dirs" /home/jason/Music/ 2>/dev/null
done
status1=$?

mpc update &>/dev/null

status2=$?
if [[ "$status1" -eq 0 && "$status2" -eq 0 ]]; then
  printf "%s\n" "Music directory updated" | dzen2 -p 3
fi

Como posso garantir que, onde existe um diretório no laptop e na unidade USB, mas o conteúdo seja um pouco diferente, os arquivos estão vinculados corretamente? Por exemplo:

drive USB :

Music -- Matthew Shipp -- Patoral Composure -- Track 1
                                            -- Track 2 etc...
                       -- Strata            -- Track 1
                                            -- Track 2 etc...
                       -- Equilibrium       -- Track 1
                                            -- Track 2 etc...

Laptop :

Music -- Matthew Shipp -- Patoral Composure -- Track 1
                                            -- Track 2 etc...

Nesse caso, nenhum link simbólico para os álbuns Strata ou Equilibrium será criado, presumivelmente porque o diretório pai (Matthew Shipp) existe.

Eu preferiria não usar rsync para copiar os dados reais, pois tenho espaço limitado nos laptops e com mpd capaz de seguir links simbólicos, não tenho necessidade de copiar os arquivos.

É possível ajustar meu script para propagar links simbólicos em diretórios pré-existentes no laptop?

    
por jasonwryan 16.01.2015 / 06:02

2 respostas

8

Como seu objetivo principal é ter uma visão combinada da sua pasta de música local e externa, eu acho que uma montagem de união via overlayfs pode ser usado, especialmente se os arquivos não estão sendo gravados.

O comando básico é, nas versões antigas do kernel (< 3.18):

mount -t overlayfs -o lowerdir=/read/only/directory,upperdir=/writeable/directory overlayfs /mount/point

Por exemplo:

$ ls Documents
374620-63301.pdf        My Kindle Content   scan0005.jpg
BPMN2_0_Poster_EN.pdf   scan0003.jpg        StrongDC++
$ ls devel
cse           ossec     ubuntu-14.04-desktop-amd64-ssh.iso
nexus         scripts   zsh-syntax-highlighting
$ sudo mount -t overlayfs -o lowerdir=$PWD/Documents,upperdir=$PWD/devel overlayfs ~/Documents
$ ls Documents
374620-63301.pdf        scan0003.jpg           
BPMN2_0_Poster_EN.pdf   scan0005.jpg    
cse                     scripts
My Kindle Content       StrongDC++
nexus                   ubuntu-14.04-desktop-amd64-ssh.iso
ossec                   zsh-syntax-highlighting

Uma desvantagem é a necessidade de sudo , o que talvez possa ser feito usando uma cuidadosa regra de NOPASSWD .

À luz da postagem do blog do Jason , o comando mount dos novos kernels muda para o uso de overlay como o sistema de arquivos, em vez de overlayfs e usando um workdir adicional. A documentação do kernel agora codifica isso :

At mount time, the two directories given as mount options "lowerdir" and "upperdir" are combined into a merged directory:

mount -t overlay overlay -olowerdir=/lower,upperdir=/upper,\
  workdir=/work /merged

The "workdir" needs to be an empty directory on the same filesystem as upperdir.

    
por 16.01.2015 / 07:18
3

Você também pode usar o gnu stow , um gerenciador de farm de links simbólicos.

Assuma o seguinte layout:

.
├── drive
│   ├── a
│   │   ├── b
│   │   │   └── bar
│   │   └── c
│   │       └── baz
│   └── b
└── music
    └── a
        └── b
            └── foo

Executar: $ stow --target music --dir drive .

Resultado:

.
├── drive
│   ├── a
│   │   ├── b
│   │   │   └── bar
│   │   └── c
│   │       └── baz
│   └── b
└── music
    ├── a
    │   ├── b
    │   │   ├── bar -> ../../../drive/a/b/bar
    │   │   └── foo
    │   └── c -> ../../drive/a/c
    └── b -> ../drive/b
    
por 18.01.2015 / 21:59