У меня есть программа, которая хранит свои настройки в ~/.config/myprogram
что я использую как в интерактивном режиме, так и с системой пакетного обслуживания. При интерактивном запуске я хочу, чтобы эта программа использовала мои файлы конфигурации (и это так). Но при работе в пакетном режиме файлы конфигурации не нужны, потому что я указываю параметры командной строки, которые перезаписывают все соответствующие параметры. Кроме того, доступ к файлам конфигурации по сети увеличивает время запуска программы на несколько секунд; если файлы не существуют, программа запускается намного быстрее (поскольку каждое задание занимает около минуты, это существенно влияет на пропускную способность пакетного задания). Но поскольку я также использую программу в интерактивном режиме, я не хочу постоянно перемещать / удалять свои файлы конфигурации. В зависимости от того, когда мои пакетные задания запланированы в кластере (в зависимости от использования других пользователей),
(Кроме того: производительность сетевых файлов настолько низкая, что, вероятно, является ошибкой, но я всего лишь пользователь кластера, поэтому я могу только обойти его, а не исправлять.)
Я мог бы создать версию программы, которая не считывает файлы конфигурации (или не имеет опции командной строки) для пакетного использования, но среда сборки этой программы плохо спроектирована и сложна в настройке. Я бы предпочел использовать двоичные файлы, установленные через менеджер пакетов моей системы.
Как я могу обмануть отдельные экземпляры этой программы, притворившись, что мои файлы конфигурации не существуют (без изменения программы)? Я надеюсь на обертку формы pretendfiledoesntexist ~/.config/myprogram -- myprogram --various-options...
, но я открыт для других решений.
LD_PRELOAD
хук. Это проще (вы можете реализовать это через час или два, если вы знаете C), чем альтернатива, которая естьptrace
. Вы также можете использовать fakechroot для этого (я думаю, что это LD_PRELOAD).Ответы:
Эта программа, вероятно, разрешает путь к этому файлу из
$HOME/.config/myprogram
. Таким образом, вы можете сказать, что ваш домашний каталог находится в другом месте, например:Теперь, возможно, вашей программе нужен какой-то другой ресурс в вашем домашнем каталоге. Если вы знаете, кто они, вы можете подготовить фальшивый дом для вашей программы со ссылками на необходимый ей ресурс.
источник
Если все остальное терпит неудачу, напишите библиотеку-оболочку, которую вы будете использовать
LD_PRELOAD
, чтобыopen("/home/you/my-program/config.interactive")
перехватывать вызов, но через него проходил любой другой. Это работает для любого типа программы, даже сценариев оболочки, так как она будет фильтровать системные вызовы.Примечание: я не проверял этот код, и я не уверен на 100%, что эта
errno
часть работает.Посмотрите как
fakeroot
это делается для звонков типаgetuid(2)
иstat(2)
.По сути, компоновщик свяжет это приложение с вашей библиотекой, которая переопределяет
open
символ. Поскольку вы не можете использовать две разные функции, названныеopen
в вашей собственной библиотеке, вы должны разделить ее во второй части (напримерget_real_open
), которая, в свою очередь, будет ссылаться на исходныйopen
вызов.Оригинал:
./Application
Перехватывается:
LD_PRELOAD=yourlib_wrap.so ./Application
Редактировать: По-видимому, есть
ld
флаг, который вы можете включить (--wrap <symbol>
), который позволяет вам писать обертки, не прибегая к двойным ссылкам:источник
Удалите ваш файл конфигурации и напишите оболочку сценария оболочки для интерактивного варианта использования, который копирует файл в его обычное место назначения, запускает программу и удаляет ее при выходе.
источник
Это должно быть возможно с unionfs / aufs. Вы создаете
chroot
среду для процесса. Вы используете реальный каталог в качестве слоя только для чтения и помещаете пустой поверх него. Затем вы монтируете том unionfs в соответствующий каталог вchroot
среде и удаляете там файл. Процесс не увидит этого, но все остальные увидят.источник
Переименуйте файл конфигурации, например, в
config.interactive
. Создайте еще один пустой файл с именем напримерconfig.script
.Теперь создайте программную ссылку под названием
config
(или то, что приложение ожидает в качестве файла конфигурации) для любой необходимой конфигурации и запустите ваше приложение.Не забудьте убрать свою ссылку позже.
источник
Если вы точно охарактеризовали, как ваша программа использует файл конфигурации, я пропустил его. Многие программы (такие как
bash
иvi
) проверяют файл конфигурации сразу после запуска; если файл существует, прочитайте его и закройте. Эти программы никогда не обращаются к этим файлам инициализации снова. Если ваша программа такая, читайте дальше.Я знаю, что вы отклонили ответы, которые делают файл конфигурации действительно несуществующим (переименовывая его), но у меня есть морщинка, которую я не видел, предложенный кем-либо еще. Сделайте это, когда вы вызываете программу в пакетном режиме:
Это удаляет файл конфигурации с пути, но затем перемещает его обратно на одну секунду позже, даже если
myprogram
он все еще работает. Это создает очень короткое окно времени, в течение которого файл недоступен - какова вероятность того, что вы запустите программу в интерактивном режиме в течение этого окна? (Даже если вы это сделаете, вы можете просто выйти и перезапустить, и файл конфигурации, вероятно, вернется на свое место.)Это создает условия гонки; если программе требуется слишком много времени, чтобы открыть файл, она может получить реальный файл. Если это происходит достаточно часто, что является проблемой, просто увеличьте значение DELAY_TIME.
источник
Мне нравится ответ Стефана, но это заставит любую программу поверить, что любой файл пуст - (потому что его dentry временно указывает на файл, который на самом деле пуст) :
Вы также можете:
Если бы вы хотели.
источник
mv
в файле - что может иметь иные последствия, кроме влияния на его зубцы, такие как фактическое усечение файла или другие и т. Д. - тогда как это действует только на ничего. Тем не менее, я долженunshare
это,mount
я думаю ...