Есть скрипт на sh, который запрещает некоторые символы. Нужно дополнить его запретом и на наличие русских букв и пробелов в названии файла.
echo "$1" | grep [а-я] работает под линуксом, а когда к скрипту обращается cvs-клиент, grep не срабатывает и выдает ошибку "grep: Invalid collation character"
Почему это? Из-за того, что win-клиент обращается с CP1251 или что? Никак не могу понять(( И как это пофиксить?
И из-за того, что echo выдает все одной строкой, не получается отловить и пробелы. Можно это как-то обойти или дать на вход скрипту аргумент командной строки другой командой, которая бы умела это?
Помогите, пожалуйста.
>Есть скрипт на sh, который запрещает некоторые символы. Нужно дополнить его запретом
>и на наличие русских букв и пробелов в названии файла.
>echo "$1" | grep [а-я] работает под линуксом, а когда к скрипту
>обращается cvs-клиент, grep не срабатывает и выдает ошибку "grep: Invalid collation
>character"Надо не запрещать, а разрешать. Создайте список всех допустимых символов в названии файла и разрешайте только их. Предполагаю, что это [a-zA-Z0-9]
если по алгоритму нужно именно запрещать, то пользовать тот-же список дозволенного. Например:
echo "$1" | grep [^a-zA-Z0-9]>И из-за того, что echo выдает все одной строкой, не получается отловить
>и пробелы.Вот тут вообще не понял про что проблема?
Подозреваю, что на вход скрипта подается что-то вроде script.sh vasja pupkin.doc - в таком случае значение переменной $1="vasja". Необходимо подавать так: script.sh "vasja pupkin.doc"
Тоже думаю, что надо разрешать. Начал копать))
>Есть скрипт на sh, который запрещает некоторые символы(check.sh)Сделал промежуточный скрипт, чтобы посмотреть, что дается программой на вход скрипта.
т.е. скрипт.sh, в котором записано:
~/check.sh `echo "$*` > /home/test/query.txt
Вывод, когда проверяет 1 файл с пробелом
File name <nb bn> is invalid
Если ~/check.sh `echo "$1*
File name <nb> is invalid
То есть, пробел не видит, несмотря на ""
Если несколько имен:
File name <nm nmM pou\ pou tu\ tu> is invalid
Здесь видно, что подаются имена с экранированным пробелом, вот только как аргумент перехватить, если "" не помогает?
сам check.sh пока сделал такой, чтобы отлавливать, что подается на вход:
if echo "$*" | grep [a-z]; then
echo "File name <"$*"> is invalid"
exit 1
fi
exit 0А, вообще, вот сама задача:
Разрешенные знаки только A-Z, a-z, 0-9, ".", "_", "-", "@",
но при этом запретить название с Верхнего регистра
То есть, скрипт должен быть:
Запустить цикл перебора аргументов, проверять пока есть аргументы, выдавать каждый аргумент по одному
проверить на разрешенные символы
если запрещенные символы есть, выдать echo об ошибке и прекратить обработку
если запрещенных символов нет, проверить следующие аргументы
если проверены все аргументы, ошибок нет, выйти с exit 0
с циклом пока не соображу, а дальше так? Если n-это поданный аргумент
if echo "$n" | grep -v [a-zA-Z0-9\_\.\-\@]; then
echo "File name <"$n"> is invalid"
exit 1
fi
exit 0
В правильном направлении иду?
Вдохновило)) Написал на одном дыхании)) Вот только будет ли работать?)) И как выразить "или"?
#!/bin/bashwhile [ gt > 0 ]; do
for i in $*
do
if echo $i | `grep ^[[:upper:]]` или `grep -v [a-zA-Z0-9\_\.\-\@]# как сказать "или"?(так и хочется or)))
echo "File name <"$i"> is invalid"
exit 1
fi
done
done
exit 0
Помогите, плиз
>Вдохновило)) Написал на одном дыхании)) Вот только будет ли работать?)) И как
>выразить "или"?
>Помогите, плиз[code[#!/bin/sh
for I in "$@"
do
`echo $I | grep -q -e "^[A-Z]" -e "[^a-zA-Z0-9_\.@\-]"`
[ "$?" -eq "0" ]&&echo "File name <"$I"> is invalid"&&exit 1
done
>Вдохновило)) Написал на одном дыхании)) Вот только будет ли работать?)) И как
>выразить "или"?
>Помогите, плиз
#!/bin/sh
for I in "$@"
do
`echo $I | grep -q -e "^[A-Z]" -e "[^a-zA-Z0-9_\.@\-]"`
[ "$?" -eq "0" ]&&echo "File name <"$I"> is invalid"&&exit 1
done
ЗЫ Скобкой в теге обшибся :)
> `echo $I | grep -q -e "^[A-Z]" -e "[^a-zA-Z0-9_\.@\-]"`не работает(( Или только начинается с "а" пропускает, если grep-у -v на второй паттерн, пропускает все. И вот это "[^a..." не пойму(( И &&echo "File... это разве не "если отработали обе команды-дать echo"? Честно говоря не пойму код))
Попробую еще раз сформулировать условия задачи:
1) разрешать все буквы латинского алфавита в обоих регистрах во всем названии файла, за исключением того случая, когда файл начинается с Верхнего регистра, т.е.
file, fILE, fIle, fiLe, filE разрешаем
File и все остальные случаи, когда 1-я буква заглавная(A-Z) запрещаем
2) Цифры(0-9) разрешаем
3) Символы "."(точка), "_"(нижнее подчеркивание), "-"(дефис), "@" (эт) разрешаем.
Все остальное запрещаем, включая пробелы и т.п.
>Попробую еще раз сформулировать условия задачи:
>1) разрешать все буквы латинского алфавита в обоих регистрах во всем названии
>файла, за исключением того случая, когда файл начинается с Верхнего регистра,
>т.е.
>file, fILE, fIle, fiLe, filE разрешаем
>File и все остальные случаи, когда 1-я буква заглавная(A-Z) запрещаем
>2) Цифры(0-9) разрешаем
>3) Символы "."(точка), "_"(нижнее подчеркивание), "-"(дефис), "@" (эт) разрешаем.
>Все остальное запрещаем, включая пробелы и т.п.if echo "test" | LANG=C grep -qvx '[-_.a-z0-9][-_.a-zA-Z0-9@]*'; then
echo "bad filename" >&2
fi
P.S.: LANG=C перед grep здесь (в моём случае) обязательно, иначе у меня при юникодной локали не работает (похоже что бага в grep).
>P.S.: LANG=C перед grep здесь (в моём случае) обязательно, иначе у меня
>при юникодной локали не работает (похоже что бага в grep).
>if echo "test" | LANG=C grep -qvx '[-_.a-z0-9][-_.a-zA-Z0-9@]*'; then
> echo "bad filename" >&2
>fiПропускает первый пробел " zmAAAA", надо принудительно обозначить начало строки.
ПС Да, создать такой файл можно ;)
>>if echo "test" | LANG=C grep -qvx '[-_.a-z0-9][-_.a-zA-Z0-9@]*'; then
>> echo "bad filename" >&2
>>fi
>
>Пропускает первый пробел " zmAAAA", надо принудительно обозначить начало строки.У меня не пропускает. Начало и конец строчки обозначать не нужно (это делает опция -x автоматически).
[c0der@xxx ~]$ if echo " zmAAAA" | LANG=C grep -qvx '[-_.a-z0-9][-_.a-zA-Z0-9@]*'; then echo "bad filename" >&2; fi
bad filename
>>Пропускает первый пробел " zmAAAA", надо принудительно обозначить начало строки.
>У меня не пропускает. Начало и конец строчки обозначать не нужно (это
>делает опция -x автоматически).Разобрался. У меня ошибка. Как обычно все дело в кавычках :)
#$I=" zzz"
#echo $I
zzz
#echo "$I"
zzz
>> `echo $I | grep -q -e "^[A-Z]" -e "[^a-zA-Z0-9_\.@\-]"`
>не работает((Оч странно. Специально сейчас прогнал все возможные варианты...
шелл какой используете?
> Или только начинается с "а" пропускает,эээ? в смысле?
> если grep-у -v на второй паттерн, пропускает все.В данном случае нельзя пускать конвеером два grep'а, потому, что получим errorlevel только по последнему
>И вот это "[^a..." не пойму(( И
[ Все, что содержит
[^ Все, что не содержит
Конструкцияgrep -q -e "^[A-Z]" -e "[^a-zA-Z0-9_\.@\-]"
Выдает $?=0, если первая буква строки заглавная "^[A-Z]" или содержит любой символ не входящий в "[^a-zA-Z0-9_\.@\-]", иначе выдает $?>0
>&&echo "File... это разве не "если отработали обе команды-дать echo"? Честно
>говоря не пойму код))Можно развернуть так:
if [ "$?" -eq "0" ]
then
echo "File name <"$I"> is invalid"
exit 1
fi>Попробую еще раз сформулировать условия задачи:
Ну как тебе сказать... Под sh(если память не изменяет, то bash немного не совместим кстати) прекрасно работает - видимо что-то где-то у тебя еще докручено - смотреть надо.
Если есть желание - стукнись в скайп (rjhdby)Попробуй заменить проверку условия, как я выше написал - может в этом дело.
да, альтлинукс, поэтому bash.
Ща попробую все это прочитать и понять))
>да, альтлинукс, поэтому bash.
>Ща попробую все это прочитать и понять))Одно дополнение.
Как правильно сказал древний - "в спорах рождается истина", спасибо phpcoder'у :)надо
echo $I
заменить наecho "$I"
В конечном счете код должен выглядеть так, правильно написал?#!/bin/bash
for I in "$@"; do
if echo "$I" | LANG=C grep -qvx '[-_.a-z0-9][-_.a-zA-Z0-9@]*'; then
echo "bad filename" >&2
fi
done
Вроде работает, надо протестить только на выход программы подать, посмотреть.
>В конечном счете код должен выглядеть так, правильно написал?
>#!/bin/bash
> for I in "$@"; do
> if echo "$I" |
>LANG=C grep -qvx '[-_.a-z0-9][-_.a-zA-Z0-9@]*'; then
> echo "bad filename" >&2exit 1
> fi
> doneexit 0
>Вроде работает, надо протестить только на выход программы подать, посмотреть.Добавил exit-ы, запустил - пробелы пропускает(( В смысле когда программа дает на вход скипта. Вчера отлавливал, он выдавал имя с пробелами в формате <tu\ tu> Мож в этом дело? \ это экранирование, но bash воспринимает \ как и продолжить строку. Как бы это поймать?
>Добавил exit-ы, запустил - пробелы пропускает(( В смысле когда программа дает на вход скипта. Вчера отлавливал, он выдавал имя с пробелами в формате <tu\ tu> Мож в этом дело? \ это экранирование, но bash воспринимает \ как и продолжить строку. Как бы это поймать?А может так? Если можно, то в том же скрипте, нет - в скрипте, который вызовет скрипт проверки
`echo $* # вызываем все параметры
grep \\ # находим \
sed "s/ # тут я пас)) Найти слева от \ посл. букву, перед ней поставить "->
#-> найти справа от нее, после пробела, последнюю букву, поставить после нее "
ищем следующий \
если \ больше нет
подать на вход скрипту проверки.
Правда, непонятно, что будет , если 2 пробела и больше. Но, наверное, пусть застрянет и все)) В смысле, в скрипте проверки, как неразрешенный пробел. Скрипт же даст exit 1