Как мне создать исполняемые файлы, которые могут работать на старых системах в современных дистрибутивах?

find[113328] кажется исключением из правила. Фактически [113329] find[113330] возникло вне группы разработчиков исходных утилит для Unix, отсюда и несоответствующий способ использования "длинных" опций.

Так часто стандартизация происходила только после того, как использование коротких и длинных опций стало обычной практикой в [113331]большинстве[113332] программ, и отчасти потому, что стали доступны некоторые подпрограммы или библиотеки для выполнения разбора опций (тем самым навязывая какой-то неявный стандарт). Но, конечно, в то время было слишком поздно изменять [113333] существующие [113334] программы, такие, как [113335] находят [113336], таким образом, чтобы не нарушать сценарии. Совместимость с POSIX, с двойными тире, менее важна, чем не нарушать эти скрипты.

Обратная совместимость, например, также является причиной того, что короткие опции для [113337]tar[113338] могут быть заданы с тире или без него.[112925].

2
12.05.2015, 14:32
1 ответ

Проблема почти определенно является псевдонимом. Когда вы делаете:

/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», но это та вещь, которая требует экспертных знаний и прямого шестнадцатеричного редактирования.

-121--150791-

Настройка старой системы в отдельной среде (chroot или VM) - самый простой способ. (В Debian, schroot и debootstrap сделать это легко; см. Как запустить 32-разрядные программы на 64-разрядном Debian/Ubuntu? )

Существует возможность перекрестной компиляции для старых версий библиотек: «просто» установите пакеты разработки для этих старых библиотек и укажите на них свой компилятор. Возможно, потребуется перекомпилировать компилятор для размещения более старой стандартной библиотеки. Сложность состоит в том, чтобы правильно установить и настроить все пакеты разработки. Вам необходимо:

  1. Скомпилировать старую стандартную библиотеку.
  2. Скомпилировать библиотеку A, указав компилятор на заголовки и файлы .a , созданные на предыдущем шаге. (С помощью gcc передайте опции -nostdinc и -nostdinc + + ; другие компиляторы обычно имеют похожие флаги.)
  3. Повторяйте, следуя цепочке зависимостей, пока программа не будет скомпилирована.
1
27.01.2020, 22:21

Теги

Похожие вопросы