Это shell-скрипт для копирования файлов разумный, четкий?


В качестве упражнения в обучении Баш, я написал этот скрипт предназначен для автоматизации процесса заполнения накопителя с несжатым .файлы AIFF скопирована непосредственно с компакт-диска. Это избавляет меня от необходимости делать кучу отдельных команд создавать поддиректории, проверьте, прежде чем крушить и т. д.

Он хранит их в этом моде:

Корневой каталог -> артист -> альбом -> диска в серии (при необходимости)

Я написал это, чтобы быть запущен в Bash на Mac. Отсюда и команду "открыть".

  1. Какие лучшие практики я игнорирую?

  2. Любое из логики излишне сложным? (За исключением все усилия, которые я думаю, я мог бы просто сделать через GUI... но где в этом веселье?)

В частности, интересно про сравнение содержимого каталога источника в каталог назначения вывода содержимого назначения в текстовый файл и выполняется обратный поиск грэп на него:

for trackname in $(ls -1 /Volumes/$the_disc | grep -vf ~/.harvest/existing); do

Спасибо за любую обратную связь вы можете предложить этот Новичок.

#!/bin/bash

# > harvest.sh <
# Identifies audio CDs and copies their contents to my archive directory
# Written by parisminton for Concrete Daydreams.
# <parisminton@da.ydrea.ms>

vrs='v 0.7'
lastchange='8/15/11'

echo -e "\n--> Harvest $vrs $lastchange <--"

# ...change IFS to newline...
OLD_IFS=$IFS
IFS=$'\n'

i=0

tryagain="--> I can't find any more external volumes. Are you sure you inserted a CD or external drive?\n"

function y_or_n () {
  until [ "$pick" == "y" -o "$pick" == "n" ]; do
    echo -e "--> (Enter \"y\" or \"n\".)\n"
    read pick
  done
}

function collect () {
  the_disc=$1
  multi=null
  ls /Volumes/$1
  echo -e "\n--> What's the artist's name?\n"
  read artist
  echo -e "\n--> OK. We're storing music from $artist."

  echo -e "\n--> Is \"$1\" the name of the album?"
  pick=null
  y_or_n

  if [ "$pick" == "y" ]; then
    echo -e "\n--> Excellent. $1 is the name of the album by $artist.\n"
    album=$1
  else
    echo -e "\n--> What's the name of the album?\n"
    read album
    echo -e "\n--> Excellent. $album is the name of the album by $artist."
  fi

  echo -e "\n--> Is \"$album\" a multi-disc set?"
  pick=null
  y_or_n

  if [ "$pick" == "y" ]; then
    echo -e "\n--> Which disc is this? (\"1,\" \"Disc 1,\" \"The Love Below,\" \"etc...)\n"
    read multi
    if [[ "$multi" =~ ^[0-9]+$ ]]; then
      multi="Disc $multi"
    fi
  fi
}

function archive () {
  musicpath="/path/to/music/directory/"

  if [ ! -e "$musicpath/$artist" ]; then 
    mkdir "$musicpath/$artist"
    echo -e "\n--> I just created a folder named \"$artist.\""
  else
    echo -e "\n--> $artist already has a folder in the archive."
  fi
  cd "$musicpath/$artist"

  if [ ! -e "$musicpath/$artist/$album" ]; then
    mkdir "$musicpath/$artist/$album"
    echo -e "\n--> I just created a folder named \"$album.\""
  else
    echo -e "\n--> The album \"$album\" already has a folder in the archive."
  fi
  cd "$musicpath/$artist/$album"

  if [ "$multi" != null ]; then
    if [ ! -e "$musicpath/$artist/$album/$multi" ]; then
      mkdir "$musicpath/$artist/$album/$multi"
      echo -e "\n--> I just created a folder named \"$multi.\""
    else
      echo -e "\n--> \"$multi\" already has a folder in the archive."
    fi
    cd "$musicpath/$artist/$album/$multi"
  fi

  mkdir ~/.harvest
  ls -1 . > ~/.harvest/existing
  tracktotal=$(ls -1 /Volumes/$the_disc | grep -cvf ~/.harvest/existing)

  if [ $tracktotal -gt 0 ]; then
    open .
    trackcount=0
    for trackname in $(ls -1 /Volumes/$the_disc | grep -vf ~/.harvest/existing); do
      trackcount=$(($trackcount+1))
      echo -e "\n--> Copying \"$trackname.\" This may take a minute or two..."
      cp "/Volumes/$the_disc/$trackname" .
    done
    echo -e "\n--> Finished copying."
    echo -e "\n--> $tracktotal tracks from the album \"$album\" by $artist have been saved to $(pwd)."
  else
    echo -e "\n--> Nothing copied. All the files on $album have already been archived.\n"
  fi

  rm -PR ~/.harvest
}

# ...compare the /Volumes list to the pre-defined list of internal volumes
# we know aren\'t the audio CD; any inverse matches are likely to be the
# CD we want to archive...
if [ "$(ls -1 /Volumes | grep -vf ~/.int_vols)" ]; then

  for filename in $(ls -1 /Volumes | grep -vf ~/.int_vols); do
    if [ -d "/Volumes/$filename" ]; then
      fn[$i]=$filename
      i=$(($i+1))
    fi
  done

  if [ ${#fn[*]} -gt 1 ]; then
    echo -e "\n--> I see more than one volume that might contain the music you want to archive:\n"

    PS3="--> Which one do you want? (Type the number of your choice.) "

    select disc in ${fn[*]}; do
      echo -e "\n--> Cool. You selected $disc.\n"
      break
    done

    collect $disc
    archive

  else
    echo "\n--> Does the volume named \"${fn[0]}\" contain the music you want to archive?"    
    y_or_n
    if [ "$pick" == "y" ]; then
      collect ${fn[0]}
    else
      echo $tryagain
    fi
  fi

else
  echo $tryagain
fi

# ...restore IFS...
IFS=$OLD_IFS


279
3
задан 16 августа 2011 в 06:08 Источник Поделиться
Комментарии
1 ответ

Некоторые комментарии:


  1. Вы скрипт не работает, если у вас есть пробелы в именах файлов, но я думаю, этого не случится.

  2. Вам не нужно, чтобы восстановить МФС как скрипт будет работать в подпроцесс, и не влияет на родительской среде.

  3. Вы можете запустить Общ -1 /объемы | грэп -ВФ ~/.int_vols только один раз, делать имена файлов=$("ЛС" -1 /объемы | грэп -ВФ ~/.int_vols) перед Если.

  4. Вас может спасти тесты В для петли с помощью найти /Тома -mindepth 1 -maxdepth с 1 -типа Д | вырезать -Д "/" -Ф 3 вместо ЛС -1 /Тома.

  5. Вы смогли сохранить весь для петли делаем найти /Тома -mindepth 1 -maxdepth с 1 -типа Д | вырезать -Д "/" -Ф 3 | Вставьте -с -д "" | читай-Ф

В кат-Д "/" -Ф 3 не очень хорошо работает, если вы измените /томов на каталог, который находится не прямо под /. Я хотел бы использовать СЭД -е с|.*/|| вместо этого, но это вводит новый инструмент, который вы не могли быть знакомы.

Для остальной части скрипта, я не знаю структуру данных, поэтому я не могу сказать.

3
ответ дан 16 августа 2011 в 10:08 Источник Поделиться