2015-06-24 3 views
-1

Я пытаюсь написать Bash Script, который будет создавать символические ссылки, но исключать определенные файлы.Symlink Exclude in Bash Script

Я уже посмотрел эту тему, но это не помогает мне:

https://serverfault.com/questions/165484/how-to-symlink-folders-and-exclude-certain-files

Так что это сценарий я использую в данный момент:

#! /bin/bash 
target=/home/csgo/game/output 
cs=/home/csgo/game/csgo-deagle1 

exclude=("*.conf" "*.cfg" "*txt" "*.ini" "*.smx" "*.mp3" "*.sh")  

for file in ${cs}; do 
    for ((index = 0; index < ${#exclude[@]}; index++)); do 
     if [[ ${file} != ${exclude[${index}]} ]]; then 
      ln -s ${file} ${target} 
     elif [[ ${file} == ${exclude[${index}]} ]]; then 
      cp ${file} ${target} 
     fi 
    done 
done 

Сценарий должен посмотрите в списке исключений, и если расширение исключено, оно не должно содержать символическую ссылку; он должен скопировать файл вместо него.

В настоящий момент скрипт создает символическую ссылку в каталоге, но все внутри него копируется.

+0

В качестве побочного примечания, 'elif' является излишним. 'If' уже оценил условие, а' cp' должен просто находиться в ветке 'else'. Не нужно снова проверять одно и то же. – tripleee

+0

Более тангенциально, '$ {file}' эквивалентно '$ file', а фигурные скобки необходимы и полезны, когда вам нужно интерполировать переменную в середине какого-либо другого текста, например' foo $ {file} bar' vs 'foo $ filebar' (где последний ссылается на предположительно несуществующую переменную' $ filebar') – tripleee

ответ

1

Вы сравниваете литые строки в списке exclude. Имя файла буквально не равно *.conf, поэтому сравнение возвращает false.

В любом случае, я бы пропустил массив и просто использовал case.

#! /bin/bash 

# I don't see the value of these variables, but more power to them 
target=/home/csgo/game/output 
cs=/home/csgo/game/csgo-deagle1 

# Hmmm, this will only loop over the actual directory name. 
# Do you mean for file in "$cs"/* instead? 
for file in $cs; do 
    case $file in 
     *.conf | *.cfg | *txt | *.ini | *.smx | *.mp3 | *.sh) 
     cp "$file" "$target";; 
     *) 
     ln -s "$file" "$target";; 
    esac 
done 

Также обратите внимание на proper quoting of "$file" and, generally, any variable which contains a file name.

(Существует в настоящее время ничего Bash конкретный в этом сценарии, так что вы можете изменить хижину к #!/bin/sh, тоже.)

Менее навязчивое изменение будет использовать =~ вместо этого, но тогда вы должны переключиться на regexes вместо шаблонов glob для списка исключений. Но вышеприведенный подход более эффективен, так как он избегает явного внутреннего цикла.

+0

Я принял '* txt' без точки до того, как расширение не было опечаткой; если бы это было, очевидно, вы захотите его исправить. – tripleee

+0

Возможно, мое объяснение было плохим. У меня есть один каталог, это Мастер-каталог. Скрипт должен проверять каждый файл в каталоге и создавать Symlink. Когда файл представляет собой файл конфигурации типа «test.cfg» или что-то еще, перечисленное в списке исключений, он должен его скопировать. Вывод файлов с символикой и копируемых файлов должен выполняться в каталоге вывода. Я не так хорош в Bash, так что это очень сложно для меня: D – tilloo3

+0

Помимо ошибки в вашем исходном скрипте, который я прокомментировал в коде (цикл над файлами в каталоге, а не только с именем каталога), я верю это должно соответствовать вашим требованиям. Если это не удается, как это происходит? – tripleee