Хто має справу з зіркою * в ехо *


15

Хто займається (тлумачить) * в

echo *

Чи бачить відлуння зірка чи оболонка про це і повертає список імені файлу ..

Що стосовно

cp temp temp*

14
Він змінюється. Оболонки Unix або оболонки Windows?
користувач1686

Оболонки @grawity Unix. Вибачте, що не згадав про це.
faressoft

Для Unix відповіді нижче є правильними. (У Windows це робиться за окремими програмами, хоча зазвичай це автоматично бібліотека часу виконання перед main ().)
user1686

Відповіді:


24

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

У більшості випадків це досить непомітно, але час від часу може призводити до деяких заплутаних випадків.

Розглянемо наступне. Каталог містить цей вміст:

  • тест (звичайний файл)
  • test1 (каталог)
  • test2 (каталог)
  • test3 (каталог)

Якщо ви введете mv *щось, здавалося б, дивне трапляється: test3є, але решта вже немає. У той час як спочатку дивно, це має сенс, як тільки ти зрозумієш, до чого насправді переходить баш mv. Через зірочку bash інтерпретує mv *як mv test test1 test2 test3, і коли mv потрапить до цього списку, ви вважатимете, що остання аргументація - це пункт призначення, куди було б переміщено всі файли.

Щодо перерахованих вами команд:

  • echo *може функціонувати як бідняки ls. Оболонка розширить зірочку на все, що є в цьому каталозі, і, як я впевнений, ви вже знаєте, echoбуквально просто відлучить все, що баш передається йому як аргументи.
  • 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 *.* це не кліше.

Примітка. Я додаю, що побачивши деякі коментарі, існує ризик запуску *, а потім УВІДКА. Якщо у вас є файл з назвою rm, який є першим у списку каталогів, то це небезпечно, оскільки все після нього буде видалено. Крім того, і це менш малоймовірно, якщо перший файл у списку каталогів - це ім'я скрипту на шляху, то він запустить це.


4
Зверніть увагу, тут може бути файл з ім'ям rm.
Volker Siegel

1
... і ще один називається -rf
ǝɲǝɲbρɯͽ

1
@ ǝɲǝɲbρɯͽ чи можете ви мати файл, ім'я якого файлу -rf? Я спробував touch -rfі , touch \-rfале це не створює його.
барлоп

@barlop Я коментував вище; gui (як gedit) справляється з ними чудово, але оскільки оболонка (принаймні баш) проходить це через неї, потрібно ./ спереду. Якщо ви коли-небудь випадково створюєте такий файл, rm намагається натякнути, але якщо ні: я сподіваюся, що це лише коли-небудь потрапляє у темп-папку з одноразовими дітьми.
ǝɲǝɲbρɯͽ

@ ǝɲǝɲbρɯͽ Я взагалі не розумію, що ти маєш на увазі, я запитую, як можна створити файл, названий -rf? (Я розумію небезпеку файлу під назвою rm та файлу під назвою -rf, і проблема введення * та натискання клавіш увійти у важливу папку, я цього не збираюся робити)
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.