2013-09-01 2 views
2

я создаю скрипт для копирования файлов или папки с датой, прикрепленной к его имени, например, если имя файла test будет test-20130901.bkupпсевдонимов команд в моем сценарии

и это мой сценарий

#!/usr/bin/bash 
set -x 

getopts fd TYPE 
[ $TYPE = "d" ] && alias cp="cp -r" 

backup_error() { 
     echo "${0##*/}: $1" 
     exit -1 
} 

typeset -r FROM_DIR=$2 TO_DIR=$3 
if [ ! -e $FROM_DIR -a ! -d $FROM_DIR ] || [ ! -e $TO_DIR -a ! -d $TO_DIR ] 
then 
     backup_error "One of the directories isn't exist or it maybe a file"; 
fi 

typeset -r DATE=$(date "+%Y%m%d") 
for filename in $FROM_DIR/* 
do 
     if [ -$TYPE $filename ] 
     then 
       cp $filename $TO_DIR/${filename##*/}-$DATE.bkup 
     fi 
done 

unalias cp 

В скрипте я проверяю, хочет ли пользователь запускать скрипт только в файлах или только в каталогах. -f для файлов только -d для каталогов только

[ $TYPE = "d" ] && alias cp="cp -r", эта строка для проверки, если скрипт работает для каталога, я должен использовать cp -r поэтому я сделать псевдоним для cp быть cp -r

, но когда я использую set -x для debug Я нахожу, когда пользователь использует -d опцию команды cp в if, все еще оригинальной, а не псевдонимом.

Debugging:

> ./backup.sh -d . . 
+ getopts fdb TYPE 
+ '[' d = d ']' 
+ alias 'cp=cp -r' 
+ typeset -r FROM_DIR=. TO_DIR=. 
+ '[' '!' -e . -a '!' -d . ']' 
+ '[' '!' -e . -a '!' -d . ']' 
++ date +%Y%m%d 
+ typeset -r DATE=20130901 
+ '[' -d ./backup.sh ']' 
+ '[' -d ./dir1 ']' 
+ cp ./dir1 ./dir1-20130901.bkup 
cp: ./dir1: is a directory 
+ '[' -d ./file1 ']' 
+ '[' -d ./file2 ']' 
+ '[' -d ./test.sh ']' 
+ unalias cp 
+0

[$ TYPE = "d"] && __cp = "cp -r" || __cp = "ф" , а затем .... $ __ ф $ имя_файла $ TO_DIR/$ {имя файла ## * /} - $ DATE.bkup просто выплеснуть сглаживанием/unaliasing подход)) –

+0

Это хорошо, но знаете ли вы какие-либо оправдания тому, что произошло? –

ответ

2

Используйте функцию вместо:

if [[ $TYPE == d ]]; then 
    function cp { 
     command cp -r "[email protected]" 
    } 
fi 

И когда в Bash, [[ ]] рекомендуется над test или [ ].

Также укажите, пожалуйста, ваши переменные должным образом между "", чтобы предотвратить разделение слов и непредвиденное расширение имени пути.

Другие предостережений:

exit -1 ## exit can only accept 8-bit integral values from 0 to 255. -1 here is orthodox and is equivalent to 255. 

Вы должны процитировать переменные здесь или использовать [[ ]]:

if [[ ! -e $FROM_DIR && ! -d $FROM_DIR ]] || [[ ! -e $TO_DIR && ! -d $TO_DIR ]] 

    if [ "-$TYPE" "$filename" ] ## for custom operators, test is better: test "-$TYPE" "$filename" 

      cp "$filename" "$TO_DIR/${filename##*/}-$DATE.bkup" 

for filename in "$FROM_DIR"/* 

Наконец убедитесь, что вы запустите скрипт как:

bash script.sh -f from_dir to_dir 
# Or 
bash script.sh -d from_dir to_dir 
+0

Это хорошо, но знаете ли вы какие-либо оправдания тому, что произошло? –

+0

@M_E В соответствии с здесь: http://www.gnu.org/software/bash/manual/html_node/Aliases.html, * Псевдонимы не разворачиваются, если оболочка не является интерактивной, если параметр оболочки expand_aliases не установлен с использованием shopt *. И это не только то, что: * псевдонимы, определенные в функции, недоступны до тех пор, пока эта функция не будет выполнена. Чтобы быть в безопасности, всегда ставьте псевдонимы в отдельной строке и не используйте псевдоним в составных командах. * – konsolebox

+2

Так или иначе, когда внутри скрипта или под псевдонимами подсели вообще не расширяются. Это как-то сбивает с толку, и они также не были уверены, что его реализация стабильна или одинакова в каждой версии bash. Именно по этой причине функции наиболее предпочтительны внутри сценариев и даже в интерактивных средах. – konsolebox

Смежные вопросы