Перш ніж grepпобачити аргумент командного рядка, цей аргумент аналізується оболонкою. Для оболонки *є підстановкою для "всіх неточних файлів у поточному каталозі". Оскільки оболонка спочатку обробляє аргумент, ваш рядок перетворюється на такий:
cat abcd | grep abcd otherfile zfile
(якщо припустити, що ці три файли перебувають у вашому поточному каталозі). Це те, що grepвидно зі своїх аргументів, але це не те, що ви хочете.
Натомість ви можете поставити шаблон для grepлапок, щоб він не оброблявся оболонкою:
cat abcd | grep "*"
Це краще, але все-таки не те, що ви хочете: grepвикористовує регулярні вирази, а не символи символів. Зірочка grepозначає, що "0..n повторень попереднього символу" - символ, який ви не вказали. Близько, але сигари немає.
Якщо ви хочете "будь-який" шаблон, ви шукаєте "0..n повторів довільного характеру". Останній представлений періодом ( '.') у регулярних виразах:
cat abcd | grep ".*"
Це те, що ви шукали.
Правка: Інший випадок легше пояснити. З grep ""вами шукаєте порожню рядок, який присутній як підряд у будь-якому рядку.
_? На моїй машині, вона дає,_: command not found.