LINUX.ORG.RU

Строка с \0 разделителем. Процесс и параметры. Как бы всё сделать хорошо и не устать

 


0

2

Из /proc/{}/cmdline я получаю имя процесса и список его параметров. В качестве раделителя там используется \0. Само по себе это не проблема, проблема в том, что дальше я храню эти данные в раширенных атрибутах файла и мне нужно чтобы пользователь мог получить данные с помощью каких-то своих третьих утилит, поэтому я заменяю \0 на пробелы.

И всё бы хорошо, но мне теперь понадобилось отрезать параметры чтобы получить чисто название процесса. Доступа к /proc/{}/cmdline уже нет, поэтому работать нужно со строкой с пробелами.

Но ведь у нас может быть ситуация, когда кто-то нафигачит пробелов в путь? Может. Редко, но в мире где есть гентушники возможно всё.

Использовать длинные уникальные сепараторы я не хочу, поскольку это испортит картину для тех, кто будет читать атрибуты с помощью третьих программ.

Пока у меня 2 идеи: использовать \t вместо пробелов. Парсить легко и выглядит как пробел. Чуток сломается обратная совместимость, но это не очень критично.

Вторая идея: забить на проблемы с пробелами и продолжать их использовать. Пофиг на мелкие неприятности которые вылезут если у кого будет пробел в пути или названии бинарика.

Вот какие есть мнения по этому поводу?

Использовать символы, которые недопустимы в путях. Знак вопроса, двоеточие. Можно даже обрамить пробелами, чтобы легче читать было. Или, скажем, что-то юникодное, что никогда в обычной жизни не используется. Например, вообще несуществующие символы из конца таблицы.

COKPOWEHEU
()
  1. Звучит как проблема XY.
  2. Почему бы не продолжить использовать \0? Что мешает сохранить эти данные в расширенных атрибутах?

Документация говорит:

Keys are generally assumed to be ASCIIZ strings, whereas values can be strings or binary data.

Chiffchaff
()
Ответ на: комментарий от Chiffchaff

Почему бы не продолжить использовать \0?

Что-то мне посказывает что большинство программ которые читают файловые атрибуты просто отрежут данные по \0.

tempUser
() автор топика

поскольку это испортит картину для тех, кто будет читать атрибуты с помощью третьих программ.

Если ты топишь за удобсто использования «третьих программ», то тебе следует использовать такой разделитель, который они понимают без проблем.

u5er ★★★
()
Ответ на: комментарий от COKPOWEHEU

Двоеточие нельзя? Хм. Прикольно.

Да ладно. Нельзя. Можно. Всё можно кроме слеша и нуля. Откуда информация про двоеточие?

tempUser
() автор топика
Последнее исправление: tempUser (всего исправлений: 1)
Ответ на: комментарий от tempUser

Только из памяти. Когда-то Thunar ругался на некоторые символы вроде того же вопроса. Собственно, я ведь не конкретное решение озвучил, а подход. Список запрещенных символов ТС может найти и сам, а также выбрать какие из них ему больше по душе.

Всё можно кроме слеша и нуля.

И что, ни у каких программ с этим не будет возникать непредвиденных проблем? Ох не верю.

COKPOWEHEU
()
Ответ на: комментарий от COKPOWEHEU

И что, ни у каких программ с этим не будет возникать непредвиденных проблем?

Ну это, вроде, часть POSIX. Так что не должно быть проблем. Даже NTFS позволяет использовать любые символы, кроме / и \0, но вот это уже будет проблемой для Windows.

anonymous
()
Ответ на: комментарий от COKPOWEHEU

Ну это баги thunar-а. Гуи вообще повсеместно забагованное, не стоит на него равняться. Помню тут на лоре кто-то показывал скрин с каким-то популярным DE который даже файлы с пробелами корректно открыть в ассоциированной проге не мог.

В путях может быть любой символ кроме \0. В именах файлов ещё не может быть слэша (/) потому что ядро его парсит как разделитель имён всегда. Всё остальное (включая спецсимволы типа переводов строк) может. То что знаки вопроса и звёздочки используются как wildcard это фича шелла, ядро и драйвер фс про это ничего не знают.

firkax ★★★★★
()

не хочу, поскольку это испортит картину для тех, кто будет читать атрибуты с помощью третьих программ

С этим требованием задача нерешаемая. Любой заменитель нуля (и \t тоже) может оказаться частью пути, так что тебе в любом случае придётся использовать какой-то символ двойным назначением а юзера заставлять зрительно определять в каком смысле он использоуется именно тут.

Обычно такие штуки решают экранированием (\\ -> \, \0 -> разделитель, например), но это означает что придётся целых два символа задействовать.

Относительно комфортный вариант - использовать двойной слэш (//), т.к. в пути он, если его и впишут, синоним к одинарному (ну и надо проверять это). Но всё равно выглядеть будет плохо.

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

Вторая идея: забить на проблемы с пробелами и продолжать их использовать. Пофиг на мелкие неприятности которые вылезут если у кого будет пробел в пути или названии бинарика.

Это означает плодить ещё больше забагованного софта.

firkax ★★★★★
()
Ответ на: комментарий от firkax

С этим требованием задача нерешаемая.

Я ищу рациональное решение, а не формально корректное. Например, если пробел в пути я ещё могу представить, то табуляцию – нет. Или использовать три пробела – человек не заметит, а кто пихает три подряд пробела в название файла, тот сам себе попингуй.

Но да, я предварительно поиграюсь с оригинальными \0, но практически уверен, что там будет песец.

tempUser
() автор топика
Ответ на: комментарий от tempUser

Я ищу рациональное решение, а не формально корректное.

С формально некорректным решением делай только для себя, не надо публиковать, подставишь в итоге кого-нить, кто, не разобравшись, понадеется на корректную работу.

firkax ★★★★★
()

Подозреваю, что третьим программам (и вообще всем кроме тебя) твои данные никуда не уперлись и никакой ценности не представляют. Зачем их пихать в атрибуты?

Если ты составляешь список исполняемых файлов, которые когда-либо запускались вместе с их cmdline - храни эти данные где-нибудь в SQLite. Или в текстовом файле.

Chord ★★★★
()

Технически правильный подход это использовать нули. Всё остальное может попадаться в имени файла.

Если искать другие решения, в первую очередь приходит в голову двоеточие. Это относительно общепринятый в юниксе разделитель (например $PATH). Также двоеточие запрещено в винде, т.е. у опытных пользователей может быть какой-то неосознанный рефлекс против использования двоеточий в именах файлов, у меня - точно есть.

Если кто-то таки создал файл с двоеточием, ты можешь это двоеточие экранировать обратной косой чертой, ну и её саму придётся экранировать. Это будет с одной стороны понятно техническому пользователю, с другой стороны это можно однозначно парсить, с третьей стороны и двоеточие, и обратная косая черта в имени файла попадаются редко (кошмар виндузятника, хе-хе).

Ещё могу предложить какую-нибудь юникодную дрисню, которая точно не попадётся в имени файла, если специально не постараться. Там и пробелов штук 10 разных, и слеши всякие есть, и чего угодно можно найти.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 2)
Ответ на: комментарий от anonymous

Возможно, это было на SMB или NTFS. https://ibb.co/8n0Xcqb4

Вот точно не вспомню, но вроде бы обычный ext4. И вполне возможно, что это действительно ограничение не ФС, а файл-менеджера. Другое дело, что если такое ограничение есть у файл-менеджера, то и у других распространенных программ оно тоже будет. А значит, здравомыслящий юзер не будет пихать подобное в имя файла.

Другое дело, что это не спасет, например, от автоименования при скачивании чего-то из интернета. Там-то и вопросы, и все, что угодно бывает.

Вариант с символом юникода, как мне кажется, наименее опасный из костыльных. Тоже, конечно, не гарантия, но надо очень постараться чтобы оно сломалось.

Не-костыльный это, естественно, менять сам способ хранения строк. Мало ли, в base64 перевести… Но тут ТСу виднее насколько сложным это будет в его случае.

COKPOWEHEU
()
Ответ на: комментарий от alysnix

ноль это конец строки

Да, но ты же при вводе строки всегда нажимаешь Enter? Тогда конец строки будет выглядеть так: \n\0.

yars068 ★★★★★
()
Последнее исправление: yars068 (всего исправлений: 1)

храню эти данные в раширенных атрибутах файла

В аттрибутах или аттрибуте? Что мешает хранить парметры как отдельные аттрибуты?

thunar ★★★★★
()