find[113328] кажется исключением из правила. Фактически [113329] find[113330] возникло вне группы разработчиков исходных утилит для Unix, отсюда и несоответствующий способ использования "длинных" опций.
Так часто стандартизация происходила только после того, как использование коротких и длинных опций стало обычной практикой в [113331]большинстве[113332] программ, и отчасти потому, что стали доступны некоторые подпрограммы или библиотеки для выполнения разбора опций (тем самым навязывая какой-то неявный стандарт). Но, конечно, в то время было слишком поздно изменять [113333] существующие [113334] программы, такие, как [113335] находят [113336], таким образом, чтобы не нарушать сценарии. Совместимость с POSIX, с двойными тире, менее важна, чем не нарушать эти скрипты.
Обратная совместимость, например, также является причиной того, что короткие опции для [113337]tar[113338] могут быть заданы с тире или без него.[112925].
Проблема почти определенно является псевдонимом. Когда вы делаете:
/bin/bash somefile
Вы загружаете новую оболочку. У тебя новый старт. Этот исполняемый файл не оседлан всеми материалами, которые вы помещаете в файлы инициализации - rc - потому что они исходят только по умолчанию для интерактивных оболочек, что не говоря уже о какой-либо дополнительной логике, накопленной с тех пор.
Псевдонимы странные. Псевдонимы являются расширениями синтаксического анализатора - они являются самым первым видом расширяемого объекта, который поддерживает большинство оболочек, и они расширяются пути многие не ожидают. bash
фактически препятствует их использованию - по какой-либо причине - путем отключения расширения псевдонимов
по умолчанию в любой неинтерактивной оболочке. И если псевдоним вызывает эту ошибку - и я почти уверен, что это проблема - то даже поиск источника файлов среды, скорее всего, все равно не вызовет такой же вывод ошибки, когда вы /bin/bash
, в любом случае.
Когда я говорю, что псевдонимы странно, это потому, что они расширены на другом уровне, чем другие типы расширения оболочки. Вероятно, это наиболее очевидно в контексте определения функции; где не происходит расширения оболочки - так как они зарезервированы для последующего выполнения функции - , за исключением псевдонимов без двойной оценки выражения. И псевдонимы никогда не расширяются во время выполнения функции (опять же, за исключением eval
) , потому что они были уже расширены во время ее определения.
Вот пример:
alias a='echo not a;b'
b(){ echo a\?; }; a(){ echo le sigh...; }
a; b
... отпечатки...
not a
not a
le sigh...
le sigh...
При первом развертывании псевдонима
с именем a
выполняется следующее:
a(){...
Это возможно, так как parens ()
являются маркерами оболочки - не зарезервированными словами, такими как {}
, - и поэтому они могут разделять слово без пробела, что делает их особенно полезными для таких вещей, как объявления функций и массивов, так как синтаксический анализатор выполняет расширение макросов для получения исполняемого оператора. Результатом вышеуказанного расширения является...
}; echo not a;b(){
Последний раз он расширяется трансформируется:
a; b
... в...
echo not a;b; b
Вы видите, типичные расширения оболочки происходят в предварительно ограниченном контексте - они ограничены со всех сторон управляющими операторами, такими как:
\n[]{}|&();<>\'"`
Таким образом, большинство расширений оболочки служат механизмом квотирования в самих себе - кавычки, расширенные из переменной, не рекурсивно ограничивают дальнейшие цитируемые контексты, потому что расширение цитирует их. Расширение псевдонимов происходит до этого, хотя - псевдонимы расширяются, если распознаются синтаксическим анализатором при сканировании первого слова оболочки в простой команде - перед сканированием в остальной части. Так что если расширение приводит к более чем одной простой команде, ну... тогда так тому и быть.
Я предполагаю, что у вас есть псевдоним
, объявленный для func
- это было бы самым простым объяснением - но потому что псевдонимы могут связываться, если они определены с помощью конечного космоса - и также будут расширены в определении функции -нет способа знать наверняка, учитывая только ту информацию, которую вы предоставляете. Думаю, я могу воспроизвести твою ошибку. Это близко:
alias func='func('
func(){
local a b=()
echo $0
}
func
... который печатает...
bash: syntax error near unexpected token `('
bash: local: can only be used in a function
bash
bash: syntax error near unexpected token `}'
bash: syntax error near unexpected token `newline'
Так что просто сделайте:
alias func local a b echo
И дайте нам знать.
-121--87609- У вас там довольно скремблированная система. Ключевые элементы вывода mdadm --examine
:
/dev/sdc1:
Update Time : Sat Oct 11 09:20:36 2014
Events : 15084
Device Role : Active device 2
/dev/sdd1:
Update Time : Wed Oct 15 08:09:37 2014
Events : 15196
Device Role : Active device 1
/dev/sde1:
Update Time : Wed Oct 15 08:09:37 2014
Bad Block Log : 512 entries available at offset 72 sectors - bad blocks present.
Events : 15196
Device Role : spare
не удалось повторно собрать массив, поскольку /dev/sdc1
имеет меньшее количество событий, чем два других (данные на нем устарели), в то время как /dev/sde1
помечен как запасной (данные на нем не имеют отношения к состоянию Это дает только один диск, содержащий данные, в то время как для запуска трехдискового RAID 5 требуется минимум два диска. Я понятия не имею, как вы здесь оказались, так как это не похоже на типичный двухприводный сбой.
Поскольку количество событий для /dev/sdc1
и /dev/sdd1
не сильно отличается, вы можете восстановить большую часть или все данные, заставив mdadm
повторно собрать массив из этих двух томов. Вы, вероятно, захотите следовать процедуре Linux RAID Wiki , но если вы не возражаете против возможности потерять все, ключевым шагом будет mdadm --assemble --force --run/dev/sdc1/dev/sdd1
, за которым следует fsck
- это либо сработает, либо полностью уничтожит массив, и точка расширенной процедуры состоит в том, чтобы выяснить, каким образом он будет без фактического повреждения данных.
Кроме того, поскольку /dev/sdd1
и /dev/sde1
имеют одинаковые счетчики событий, вы можете восстановить все, изменив метаданные на /dev/sde
, чтобы пометить их как имеющие роль устройства «Active device 0», но это та вещь, которая требует экспертных знаний и прямого шестнадцатеричного редактирования.
Настройка старой системы в отдельной среде (chroot или VM) - самый простой способ. (В Debian, schroot и debootstrap сделать это легко; см. Как запустить 32-разрядные программы на 64-разрядном Debian/Ubuntu? )
Существует возможность перекрестной компиляции для старых версий библиотек: «просто» установите пакеты разработки для этих старых библиотек и укажите на них свой компилятор. Возможно, потребуется перекомпилировать компилятор для размещения более старой стандартной библиотеки. Сложность состоит в том, чтобы правильно установить и настроить все пакеты разработки. Вам необходимо:
.a
, созданные на предыдущем шаге. (С помощью gcc передайте опции -nostdinc
и -nostdinc + +
; другие компиляторы обычно имеют похожие флаги.)