Я быть бы Вы восстанавливать версию, обеспеченную дистрибутивом. Поэтому существует по крайней мере некоторая гарантия, что кто-то, предположительно, осторожный на самом деле протестировал ту версию на самом дистрибутиве.
Относительно управления версиями эпоха является одной идеей, но я предпочитаю, чтобы Вы изменили версию на что-то как 2:1.0~rc3+svn20090426-1ubuntu16.1custom1
, просто ради ясности. Таким образом, если Вы хотите препятствовать тому, чтобы обновления дистрибутива установили нетронутые (созданные из дистрибутива) пакеты...
Поместите пакет в hold
:
/usr/bin/sudo echo "mplayer hold" | /usr/bin/sudo dpkg --set-selections
Несколько вещей неправильно в Вашем коде:
$(...)
) без установки $IFS
Отъезд закрывших кавычки расширений является split+glob оператором. Значение по умолчанию должно разделить на пространстве, вкладке и новой строке. Здесь, Вы только хотите разделить на новой строке, таким образом, необходимо установить IFS на это как иначе, которое означает, что это не будет работать правильно, если имена файлов будут содержать пробелы или символы табуляции
set -f
.Отъезд закрывших кавычки расширений является split+glob оператором. Здесь Вы не хотите globbing, который является расширением подстановочных знаков такой как scala*
в список соответствия файлам. Когда Вы не хотите, чтобы оболочка сделала globbing, необходимо отключить его с set -f
ls
искаженный к ls -F
Проблема выше ухудшена тем, что Вы имеете ls
искаженный к ls -F
. Который добавляет /
к каталогам и *
к исполняемым файлам. Так, обычно, потому что scala
исполняемый файл, ls -F
выводы scala*
, и как globbing шаблон, это расширено до всех имен файлов, которые запускаются с scala
который объясняет, почему это походит egrep -v
не фильтрует файлы.
новая строка является столь же допустимым символом как любой в имени файла. Так анализируя вывод ls
обычно не работает. Что касается экземпляра вывод ls
в каталоге, который содержит a
и b
файлы совпадают с в каталоге, который содержит один названный файл a\nb
.
Выше egrep
отфильтрует строки имен файлов, не имен файлов
egrep
вместо grep -E
egrep
удерживается от использования. grep -E
стандартный эквивалент.
.
оператор regex.Выше, Вы использовали egrep
для включения расширенных регулярных выражений но Вы не используете ни одного расширенного РЕ определенный оператор. Единственный оператор RE, который Вы используете, .
соответствовать любому символу, в то время как похоже, что это не то, что Вы предназначили. Таким образом, Вы, возможно, также использовали grep -F
здесь. Или используйте grep -v '\.bat'
.
egrep .bat
будет соответствовать любой строке, которая содержит любой символ, сопровождаемый bat
, таким образом, это - regexp, который означает что-либо, что содержит bat
не в первом положении. Это должно было быть grep -v '\.bat$'
.
$f
неупомянутыйОтъезд закрывшего кавычки расширения является split+glob оператором. Там, Вы не хотите ни одного, таким образом, $f
должен быть заключен в кавычки ("$f"
).
echo
echo
разворачивает ANSI C escape-последовательности в его аргументах и/или рассматривает строки как -n
или -e
особенно в зависимости от echo
реализация (и/или среда).
Использовать printf
вместо этого.
for f in *; do
case $f in
(*.bat);;
(*) printf '%s\n' "$f"
esac
done
Хотя, если нет никакого нескрытого файла в текущем каталоге, который все еще произведет *
. Можно работать вокруг этого в zsh
путем изменения *
кому: *(N)
или в bash
путем выполнения shopt -s nullglob
.
Вы не должны использовать ls
проанализировать регистрирует этот путь.
Сначала набор extglob globstar shopt -s extglob globstar
затем
for f in !(*.bat)
do
printf '%s\n' "$f"
done
Используя find
find . -type f ! -name '*.bat'
Используйте оператор отрицания для более безопасной обработки файлов.
bash: !: event not found
. Почему я не должен использовать ls
таким образом?
– mike
26.08.2013, 18:41
ls
в для цикла путем я сделал это, потому что некоторые имена файлов могли содержать символы новой строки.
– mike
26.08.2013, 18:46
printf '%s\n' !(*.bat)
(можно сделать то же с rm
)
– evilsoup
26.08.2013, 19:05
find
и exec
, но цикличное выполнение было легче для меня; D
– mike
26.08.2013, 19:08
Нет ничего по сути неправильно с Вашим для цикла:
$ for f in $(ls | egrep -v .bat); do echo $f; done
Вот мой вывод для вышеупомянутой команды:
$ for f in $(ls | egrep -v .bat); do echo $f; done
fsc
scala
scalac
scaladoc
scalap
Одно предложение состояло бы в том, чтобы заключить аргумент в кавычки egrep
, как так:
$ for f in $(ls | egrep -v '.bat'); do echo $f; done
Также смотрите на Ловушки Bash Wiki для других потенциальных проблем при сценариях вещей в Bash, таких как это. В особенности это походит на самую вероятную причину, почему Вы встречаетесь с этой проблемой. Проверьте, чтобы видеть, содержит ли какой-либо из Ваших возвращаемых файлов пробелы.
Другая вещь попробовать состоит в том, чтобы включить подробную отладку Вашей команды удара, до выполнения ее так Вы видите то, что продолжается негласно.
Это позволяет отладить:
$ set -x
Затем выполните свою команду:
$ for f in $(ls | egrep -v .bat); do echo $f; done
++ ls --color=auto
++ egrep --color=auto -v .bat
+ for f in '$(ls | egrep -v .bat)'
+ echo fsc
fsc
+ for f in '$(ls | egrep -v .bat)'
+ echo scala
scala
+ for f in '$(ls | egrep -v .bat)'
+ echo scalac
scalac
+ for f in '$(ls | egrep -v .bat)'
+ echo scaladoc
scaladoc
+ for f in '$(ls | egrep -v .bat)'
+ echo scalap
scalap
Затем отключите его:
$ set +x
Учитывая примеры хорошо работают в ряде собственных систем Linux, проблема, скорее всего, базирована в имении некоторое отношение к Cygwin, и/или это - конкретные версии bash
и egrep
. Я обратил бы особое внимание на разделителя полей в Bash, $IFS
видеть, существует ли проблема между различными разделителями строки в Windows (0x0d,0x0a
) по сравнению с Unix (0x0a
).
У меня нет установки Cygwin, таким образом, у меня нет метода для доказательства этой гипотезы.
ls
используйте в for
контекст цикла.ls
просто разработан для человеческого глаза. Другой синтаксический анализ операционных систем ls
вывод по-другому.
– Valentin Bajrami
26.08.2013, 19:57
ls
не имеет значения также.
– slm♦
26.08.2013, 19:59
ls
был искажен к ls -F
.
– Stéphane Chazelas
26.08.2013, 22:53
ls -F
к моему примеру это все еще работает. Я не понимаю Ваш комментарий о globbing, выполняемом на замену команды. Я подозреваю, что другие также пропускают эти детали и следовательно почему, кажется, видят это семейство вопросов так часто здесь. Канонический ответ определенно необходим по этой теме (Вы в значительной степени запустили один с Вашего к этому Q).
– slm♦
27.08.2013, 00:05
grep
действительно работал, но из-за*
добавленныйls -F
переменнаяf
в$f
был расширен. Так или остановите расширение или удалитеF
флаг отls
команда. Противоположная команда, т.е. безv
флаг в grep, действительно работал, потому что не было ничего для расширения соответствия имени файла<filename>.bat*
кому. – mike 27.08.2013, 12:05ls -F
) был подробно остановлен замена команды ($(...)
). Если был названный файлscala*
, тот подстановочный знак был бы также расширен после расширения$f
(и Вы имели замеченный все имена файлов, запускающиеся сscala
разделенный пробелами на одной строке) – Stéphane Chazelas 27.08.2013, 12:41