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


15

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

echo *

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

Как насчет

cp temp temp*

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.

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


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


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.