Это хорошая практика, чтобы требовать конечной косой черты в именах каталогов?

9

Я хочу попросить пользователя моего скрипта bash передать путь к каталогу в качестве аргумента. Что из следующего является хорошей практикой программирования?

  • Требовать, чтобы пользователь вводил трейлинг / (косая черта)
  • Требовать, чтобы пользователь не вводил трейлинг / (косая черта)
Рохит Агарвал
источник
3
Обратите внимание, что rsyncповедение по-разному очень важно, в зависимости от наличия трейлинга /, и поэтому в некоторых случаях вы хотите нормализовать для согласованности, а в других вы бы хотели пройти чисто, чтобы реализовать то, что сказал пользователь (если они знал, что они разговаривали rsync).
sh1
Еще один, который меня недавно удивил, - это то, что он ls -l dirведет себя иначе, чем ls -l dir/если dirэто символическая ссылка на каталог.
Flimm

Ответы:

27

Лучшая практика - не предполагать ни того, ни другого

Если у вас есть доступ к утилитам / классам компоновщика пути, используйте их, если нет, напишите свой код, чтобы принять любой формат и действовать соответственно.

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

ChrisF
источник
6
Следствие: всегда анализируйте пути с помощью подходящих инструментов командной строки - dirname, basenameи readlink. Очень распространенной проблемой является использование ${path##*/}в качестве замены basename, но если путь заканчивается косой чертой, которая возвращает пустую строку вместо последнего элемента пути.
10
1
+1 за использование служебных классов. Я не могу сказать, сколько раз я видел, как разработчики заново изобретали колесо, когда дело доходит до сборки путей, когда большинство фреймворков в наше время могут это легко сделать.
RationalGeek
1
Кроме того, я очень раздражен, когда какое-то приложение требует, чтобы я делал это определенным образом. И иногда пользователь не может контролировать, как написать этот путь: иногда они пишут его, так что тогда да, они предпочитают писать с конечной косой чертой или без нее, но в тех случаях, когда пользователь автоматически завершает работу, используя TAB, многие оболочки ставят конечную косую черту, так вы бы потребовали, чтобы пользователь удалил его? И еще больше раздражает, когда приложение ведет себя по-другому, если вы помещаете косую черту в каталог, переданный в качестве аргумента ( rsyncя смотрю на вас)
Карлос Кампдеррос
Недавно мне нужно было проверить косую черту из пользовательского ввода для использования с rsync (так как он чувствителен к этим вещам). Как отметил @ChrisF, лучше не предполагать ни того, ни другого. Я придумал следующее в качестве изящного способа предположить ни то, ни другое: ${STR}$(printf \\$(printf '%03o' $(($(printf '%d' "'${STR:(-1)}")==47?0:47))))я также задокументировал это для ясности: добавьте или удалите косую черту в bash
Джон Марк Митчелл
10

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

cat /etc/hosts

так же, как

cat /////etc//////////hosts

Итак, ваш скрипт может выглядеть так:

echo -n "enter path: "
read path
if [ -f $path/myfile ]
then
  echo "found myfile!"
else
  echo "nope"
fi

и вам не нужно беспокоиться, введет ли пользователь трейлинг / в путь.

user281377
источник
5
Nit: Это не bashповедение, это делает ядро.
Blrfl
7

У покойного Джона Постела в разделе 3.2 RFC 760 был несколько полезных советов :

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

Blrfl
источник
3

Концептуально слеш не является частью имени. Косая черта - это только разделитель между именами. Мой домашний каталог / home / stefan, а не / home / stefan /.

Если вы не ожидаете косой черты, вы не ошибетесь, если она есть, как уже отмечал ammoQ. Но вы можете легко склеить имена и переменные, потому что вам не нужно указывать косую черту:

a="/home"
b="stefan"

dir=$a/$b
Пользователь неизвестен
источник
0

Требование, чтобы каталог не имел завершающей косой черты, было бы чрезвычайно раздражающим для интерактивного использования на консоли: автозаполнение с TAB автоматически добавляет завершающую косую черту для каталогов.

Поэтому вам, безусловно, нужно разрешить указывать каталоги с косой чертой.

oberlies
источник