Кто имеет дело со звездой * в эхо *

15

Кто имеет дело (интерпретирует) * в

echo *

Эхо видит звезду или оболочка заботится об этом и возвращает список имен файлов ..

Как насчет

cp temp temp*
faressoft
источник
14
Различается. Оболочки Unix или Windows?
user1686
@ Grawity Unix Shell. Извините, я не упомянул это.
tarssoft
Для Unix ответы ниже верны. (В Windows это делается отдельными программами - хотя обычно автоматически выполняется библиотекой времени выполнения перед main ().)
user1686

Ответы:

24

bash (или то, что вы используете в качестве оболочки), первым прочитает любой ввод и начнет интерпретировать специальные символы, такие как ?и *. *расширяется до любых совпадений в CWD , что означает, что звездочка заменяется указанными совпадениями.

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

Учтите следующее. Каталог имеет это содержимое:

  • тест (обычный файл)
  • test1 (каталог)
  • test2 (каталог)
  • test3 (каталог)

Если вы потом наберете mv *что-то странное, то произойдет: test3есть, а остальное пропало. Поначалу это странно, но имеет смысл, когда вы поймете, что на самом деле передает bash mv. Из-за звездочки bash интерпретируется mv *как mv test test1 test2 test3, и когда mv получит этот список, он будет предполагать, что последним аргументом является пункт назначения, куда все файлы были бы перемещены.

Что касается команд, которые вы перечислили:

  • echo *может функционировать как бедняк ls. Оболочка расширит звёздочку до того, что находится в этом каталоге, и, как я уверен, вы уже знаете, echoбуквально отобразит все, что bash передал ей в качестве аргументов.
  • cp temp temp*будет вести себя примерно так же, как mvкоманда, которую я описал выше, за исключением случаев, когда есть только один каталог с именем temp, в этом случае имя источника и назначения совпадают, то есть ничего не будет сделано.
Ярмунд
источник
8
Нет ничего «плохого» в использовании *вместо ls. Например, for f in *; doэто более надежно, чем for f in $(ls)если имя файла содержит пробел или символ глобуса. (Однако, он потерпит неудачу, если в CWD нет файлов, поэтому вам нужно проверить этот случай.)
rici
1
@rici Вот для чего shopt nullglob.
CVn
3
Что касается echo *, этот трюк может спасти вас в некоторых случаях.
CVn
2
Включение: файлы с предваряющим «-» в произвольных папках, которые вызывают нежелательные переключатели. Удалить их не очень весело, пока вы не поймете, что rm ./-stupidfile работает.
ǝɲǝɲbρɯͽ
1
@ ǝɲǝɲbρɯͽ Я заметил, что когда-то мне нужно было удалить содержимое каталога, содержащего файлы с именем файла, представляющим позиции в системе координат, от -1024x-1024 до 1024x1024. Именно тогда я впервые узнал о побеге.
Джармунд
5

Как уже говорилось, оболочка расширяется, *поэтому echoпринимайте в качестве аргументов все, что оболочка найдет в текущем каталоге. Однако обратите внимание, что если расширение ни к чему не приводит, т. Е. В том случае, если каталог не содержит не скрытых файлов, *он остается неизменным и передается как есть вызываемой команде (если нестандартные параметры не используются с некоторыми оболочками, например bash.) echo *не будет вести себя как бедняк, так lsкак первый ничего не напечатает, а второй напечатает *.

Точно так cp /tmp/temp temp*же создаст файл с именем temp*в текущем каталоге, если еще нет хотя бы одного файла, имя которого начинается с temp.

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

jlliagre
источник
4

В Bash оболочка имеет с этим дело. Вы видите, что если вы даже пытаетесь *без эха

Примечание. Исходя из некоторых комментариев, я бы предложил при запуске * ENTER создать каталог и использовать команду touch для создания некоторых файлов и убедиться, что ни один из них, или, по крайней мере, убедиться, что первый в алфавитном порядке, не является именем любого сценария или команды в пути.

$ *
bash: a: command not found

$ echo *
a a.aa a.ab a.b a.htm a.tx

Так ls *что это немного клише

В Windows *это обрабатывается командой, поэтому dir *.*это не клише.

Примечание. Если посмотреть некоторые комментарии, я бы добавил, что существует риск запуска * затем ENTER. Если у вас есть файл с именем rm, который находится первым в списке каталогов, то это опасно, потому что все, что после этого будет удалено. Кроме того, и это менее вероятно, если первый файл в списке каталогов является именем сценария в пути, тогда он запустит его.

barlop
источник
4
Обратите внимание, что там может быть файл с именем rm, конечно.
Фолькер Сигел
1
... и еще один называется -rf
ǝɲǝɲbρɯͽ
1
@ ǝɲǝɲbρɯͽ у тебя может быть файл с именем файла -rf? Я попробовал touch -rfи , touch \-rfно это не создает его.
Бароп
@ barlop Я прокомментировал выше; графический интерфейс (например, gedit) прекрасно с ними справляется, но поскольку оболочка (по крайней мере, bash) проходит через нее, требуется ./ впереди. Если вы когда-нибудь случайно создадите такой файл, rm попытается намекнуть, но если этого не произойдет: я надеюсь, что это когда-нибудь закончится только временной папкой с одноразовыми дочерними элементами.
ǝɲǝɲbρɯͽ
@ ǝɲǝɲbρɯͽ Я вообще не понимаю, что ты имеешь в виду, я спрашиваю, как ты можешь создать файл с именем -rf? (Я понимаю опасность файла с именем rm и файла -rf, а также проблему ввода * и нажатия клавиши enter в важной папке, я не планирую этого делать)
barlop
-1

Оболочка выполняет несколько расширений перед передачей аргументов команде.

Смотрите также https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion

Не относится к bash, см. Http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01

Гленн Джекман
источник
Технически то, что вы пишете, правильно, но без ссылок этот ответ на самом деле ничего не делает для ответа на вопрос. Рассмотрите возможность включения соответствующих деталей.
CVn
@ MichaelKjörling Я согласен с вещами о ссылках, но ОП просто спросил, обрабатывает ли аргументы оболочка или сама команда. В ответе Гленна просто говорится, что оболочка обрабатывает их, поэтому это приемлемый ответ на вопрос.
slhck
@slhck. Вот почему я не пометил как NAA: после разрыва ссылок осталось что- то, что решает вопрос. Это не значит, что это, на мой взгляд, хороший ответ. (Теперь я вижу, что мой первоначальный комментарий можно истолковать иначе; за это я прошу прощения, но я все еще думаю, что он имеет достаточную ценность, чтобы оставить его там, где он есть.)
CVn
@ MichaelKjörling Согласен. Я просто оставил комментарий для тех, кто пометил (и будет) помечать его как NAA.
slhck