Виконати як .test, а не ./test


26

Припустимо, я перебуваю в тій самій папці, що і виконуваний файл, мені потрібно буде ввести це для його виконання:

./file

Я б краще не вводив /, тому що /мені важко набрати.

Чи є простіший спосіб виконання файлу? В ідеалі просто простий синтаксис, наприклад:

.file

або щось інше, але простіше, ніж там, щоб вставити /символ.

Можливо, є якийсь спосіб помістити щось у /binкаталог або створити псевдонім для перекладача, щоб я міг використовувати:

p file

9
Може бути, поміняти / іншим ключем за допомогою xmodmap? Так що, принаймні, це простіше набрати
Хлопець

26
Як бічна примітка, широко/ використовується в Unix, значною мірою як роздільник каталогів. Вам, мабуть, краще знайти більш простий спосіб набрати його.
chrylis -на страйк-

7
@RossPresser Це питання має дуже мало сенсу. і ./ на початку файлу - це два абсолютно різні значення з технічних причин, які повинен знати будь-який новачок. /не важко набрати переважну більшість людей, і якщо у ОП є травма, яка перешкоджає цьому, вони повинні розглянути альтернативні розкладки клавіатури, оскільки немає можливості їм /повністю уникнути, перебуваючи в терміналі.
JFA

1
@JFA Більшість розкладок клавіатур, які використовуються в континентальній Європі, а також у Південній Америці, застосовують /shift-7, який порівняно складно набрати, навіть без травм.
nitro2k01

6
Історія редагування: " чому не можу Мережевий інтерфейс просто доручити робити всі запити в Інтернеті через віддалений хост через ssh на порт 22. " ಠ_ಠ
Derek 朕 會 功夫

Відповіді:


35

Це може бути "ризиковано", але ви могли просто мати. у вашій ПАТІ.

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


1
Насправді не зрозумійте, як це "ризиковано": мій шлях пройшов такий шлях задовго до linux, і він ніколи не викликав найменшої проблеми.
jamesqf

21
@jamesqf Це ризиковано, тому що якщо ви перейдете cdдо каталогу, що записується у всьому світі, і спробуєте використовувати команду, яка не є на вашому шляху, ви можете виконати (можливо, шкідливий) виконуваний файл з тим же ім'ям, який хтось записав у цей шлях. Це набагато гірше, якщо ви ставите .на початку свого шляху. У такому випадку, lsякщо ви спробуєте зателефонувати lsв цей каталог, буде виконано зловмисний виконуваний файл .
зафіксовано

2
Будь ласка, уникайте цього з причин, зазначених вище. pКоманда буде краще.
Гвідо

11
@jamesqf Коли це "ваша" система, і ви лише її використовуєте, це не так вже й погано. Проблема виникає (і впродовж багатьох років відключила багатьох адміністраторів Unix) у багатокористувацькій системі. На .початку цього PATH, все зловмисне користувач повинен зробити, це скинути підроблену lsкоманду у свій каталог і переконати адміністратора "подивитися на щось дивне", і вони отримали кореневий доступ.
TripeHound

1
Хороше рішення, хоча воно не спрацює, якщо файл буде названо test, як у назві запитання (оскільки testце вбудована оболонка і, ймовірно, також існує десь у вашому $PATHвже).
yellowantphil

71

.автоматично завершить./ (введіть .і натисніть Tab) принаймні в сучасних оболонках Bash, тому вам не доведеться використовувати складне або небезпечне (як PATHмодифікація) рішення.

Якщо вона не завершиться автоматично, можливо, вам доведеться встановити пакет "bash-завершення".


Ти впевнений? .має декілька кандидатів на завершення: .(поточний dir), ..(батьківський dir), .команда (котра bash забезпечує нестандартний псевдонім sourceдля) та будь-які присутні точкові файли. Можливо, bash-completionпакет ігнорує це; Я вважаю це прикро дратуючим (наприклад, це унеможливлює вкладку режиму імен dir у makeкомандному рядку, і, як правило, жахливо за допомогою файлів, повних неявних правил), тому я завжди його очищаю.
Р ..

3
Я спробував це, і так, він автоматично завершує цей шлях. Майже в кожному випадку цього хотів би звичайний користувач: я не думаю, що я ніколи не бачив dotfile, який повинен бути виконуваним, запускаючи щось у підкаталозі, набагато частіше, ніж запускати щось у батьківському каталозі, і IMO це робить проклята гарна робота з пошуку makeцілей.
l0b0

З bash 3.2 він не заповнюється автоматично. Чи може це бути новим у гри 4?
Калімо

2
@Calimo Більш ймовірне нове в останніх версіях доробку. Це далеко не фундаментальна зміна.
l0b0

42

або .. можливо, дати інтерпретатору псевдонім у файлі bashrc, а потім просто

   p  file

Можна записати таку функцію:

p() {
 ./"$@"
}

у вашому ~/.bashrc. Тоді ви зможете працювати p app argumentsзамість цього ./app arguments. Це рішення працює для виконуваних файлів будь-якого типу, включаючи сценарії та бінарні файли.

"$@"розширюється до відповідного цитованого списку аргументів, переданих функції (збереження всіх спеціальних символів від глобального чи змінного розширення), і, як вказував @Scott, bashдосить розумний, щоб передувати ./першому з них, зберігаючи решту.


Хоча для запуску програми під іншою командою це менш загальнодоступно, як strace -f p appпобачити зроблені системні дзвінки або $(which time) p appпобачити, скільки часу потрібно. pяк виконавчий сценарій би працював краще в цих двох конкретних прикладах, на які я намагався. Жодне рішення не може працювати з цим ldd p app, хоча воно ldd також відрізняється тим, що вимагає повного шляху, можливо, з таких причин.
sourcejedi

Так, заміна p app argsз ./app argsтаким способом , який є невидимим для будь-якого трубопроводу зажадає введення оболонки через яке - то препроцесор і викликатиме всі види задоволення , коли заміна відбувається в незапланований місці :)
aitap

1
У цьому випадку, чи не повинно бути цитат навколо $@? Інакше це просто передасть один великий аргумент програмі.
Кролтан

7
@Kroltan No. $@- це масив. При розширенні всередині "кожного параметра розширюється окреме слово. $*поводиться так, як ти думаєш.
8bittree

3
Я вважаю, що ви зробили це непотрібно складним, і p() { ./"$@"; }це все, що вам потрібно.
Скотт

11

Ви можете поставити .до свого $PATH, додавши, наприклад, PATH=$PATH:.у свій /etc/profile, таким чином ви можете виконати fileлише написання file, якщо це не знаходиться в якійсь іншій папці вашого шляху (наприклад /usr/bin/). Зауважте, що це, як правило, не дуже гарна ідея.

Чому це погано: Скажіть, ви потрапили в ситуацію, коли ви не повністю довіряєте вмісту каталогу - ви завантажили його звідки-небудь хитромудрі, і ви хочете дослідити його, перш ніж запустити його, або ви сисадмін, який допомагає деяким користувач, заглянувши в його домашній каталог і т. д. Ви хочете перерахувати каталог, тому ви намагаєтеся ввести ls, але, ой, ви робите помилку на друку і в кінцевому підсумку набираєте напис sl. Автор цього шкідливого каталогу передбачив це і вклав у нього скрипт оболонки під назвою "sl", який виконує "rm -rf --no -serve-root /" (або щось більш шкідливе, як встановлення rootkit).

(Дякую @Muzer за пояснення)


13
Хоча я цілковито погоджуюся, напевно, це саме пояснити, чому це не дуже гарна ідея.
ymbirtt

16
Чому це погано: Скажіть, ви потрапили в ситуацію, коли ви не повністю довіряєте вмісту каталогу - ви завантажили його звідки-небудь хитромудрі, і ви хочете дослідити його, перш ніж запустити його, або ви сисадмін, який допомагає деяким користувач, заглянувши в його домашній каталог і т. д. Ви хочете перерахувати каталог, тому ви намагаєтеся ввести ls, але, ой, ви робите помилку на друку і в кінцевому підсумку набираєте напис sl. Автор цього шкідливого каталогу передбачив це і вклав у нього скрипт оболонки під назвою "sl", який виконує "rm -rf --no -serve-root /" (або щось більш шкідливе, як встановлення rootkit).
Мюзер

2
Варто пояснити, що якщо поточний каталог знаходиться на початку $ PATH, натомість зловмисник може просто перекрити ls або інші загальні команди
Деліссон Хуніо,

@Muzer Huuuge tinfoil капелюхи тут.
Курка Сомбреро

4
@GillBates Це та річ, з якою вам слід насторожитися, як системний адміністратор, який має справу з реальними та потенційно шкідливими користувачами, або хтось, хто аналізує підозрілі архіви на життя. Якщо жодне з них не застосовується, я згоден з вами. Я все ще не думаю, що вдаватися в цю шкоду, тому що ніколи не знаєш, коли змінитимуться твої обставини, ти отримуєш одну з цих робіт, і ти будеш нескінченно проклинати себе за те, що навчив себе покладатися на невпевнену поведінку; )
Мюзер

10

Ви можете зателефонувати перекладачеві, наприклад

bash test

У цьому випадку сценарій запускається, навіть якщо він не має ані рядки shebang (наприклад #!/bin/bash), ані біту, який виконується. Вам доведеться знати правильного перекладача, щоб також його запустити. Ви можете спочатку прочитати рядок файлу shebang, щоб переконатися, що ви викликаєте правильного перекладача, наприклад, якщо в рядку shebang написано

#!/usr/bin/env python3

ви б подзвонили

python3 test

7
Інтерпретатор просто інтерпретує код, вони не запускають двійкові файли
Мак Кернель

Ця відповідь дещо логічна, тому що, можливо, інтерпретатору можна дати псевдонім у файлі bashrc.

5
@McKernel хороший момент, він працює лише за наявності інтерпретатора, а не для складених виконуваних файлів
Zanna

2
є перекладач для складених виконуваних файлів:/lib/ld.so
Дмитро Кудрявцев

7

Наскільки я знаю, немає способу досягти цього, якщо ви не включите файл у env шлях, щоб ви могли запустити його просто набравши: file

.fileне працюватиме, оскільки це інше ім'я файлу. Це файл, який називається, .fileа не ./file.

Я відчуваю, що косу рису може бути важко набрати для вас, тому що не англійська макет, можливо? У такому випадку це трапляється і зі мною, тому я часто міняю розкладку клавіатури на англійську, натискаючи Alt + Shift в Windows (я використовую Linux від ssh)


7

Люди запропонували додавати .до цього PATH, що небезпечно, оскільки це створює ризик випадкового запуску шкідливої ​​програми, закладеної у каталог, що записується у світі. Але, якщо у вас є виконувані програми в декількох каталогах , якими ви володієте і доступні для запису тільки вам, то це безпечно (досить безпечно?) Поставити ці директор (е) в PATH, додаючи рядок

PATH=$PATH:~/dev/myprog1:~/dev/myprog2

у ваш ~/.bashrcфайл. Звичайно, це означає, що ви можете запускати програму з одного з цих каталогів з будь-якої точки файлової системи. Наприклад, ви можете cd /etcввести fooі він буде працювати ~/dev/myprog1/foo. Це має незначний недолік, що ви не можете мати однойменні програми в більш ніж одному з каталогів. Зокрема, якщо у вас є програми, викликані і foo в обох, ~/dev/myprog1і ~/dev/myprog2ви не зможете запустити другу, крім вказівки шляху. Так само, якщо у вас є ~/dev/myprog1/cat- але чому б ви хотіли?


Інший підхід, якщо у вас є лише кілька програм, з якими ви це робите, - це визначити псевдоніми для них:

alias gizmo='./gizmo'
alias gonzo='./gonzo'

Або ви можете назвати псевдоніми, .gizmoі .gonzo якщо вам здається, що це інтуїтивніше.

Насправді, це певною мірою є таким же ризиком для безпеки, що і .для вашого PATH. Якщо зловмисний користувач може прочитати ваші .bashrcпсевдоніми і побачити ваші псевдоніми, він може поставити виклик зловмисного програмного забезпечення gizmoта gonzoвипадкові каталоги в надії, що ви його запустите. Краще використовувати ці абсолютні імена:

alias gizmo='~/dev/myprog1/gizmo'
alias gonzo='~/dev/myprog2/gonzo'

До речі, вам слід уникати імен виконуваного файлу test, тому що це команда, вбудована в оболонку, і ви можете запустити програму під цим ім'ям, лише вказавши шлях або якийсь інший трюк.


Крім того, ви можете скласти рецепт (якщо ви використовуєте Makefiles, який є) і зробити make gizmoабо make gonzo.
ihato

Вибачте, але я не впевнений, що розумію, як це стосується питання чи моєї відповіді. Чи пропонуєте ви ОП створити Makefileу кожному каталозі таке, що дії для make gizmoзакінчення виконуються gizmo ? (1) Це здається незграбним способом виконувати те саме, що і pфункція, запропонована у питанні, спочатку реалізована aitap та уточнена Скоттом. (2) Чи можете ви передати аргументи таким чином? ISTM, що make gizmo arg1 arg2еквівалентно make gizmo; make arg1; make arg2.
G-Man каже: "Відновіть Моніку"

1
(1) Можливо, моє припущення неправильне, але мені незрозуміло, що ОП хоче відмовитися від використання ./у кожному каталозі . На мою думку, він щось розробляє і просто повинен ./fileчасто запускати створену програму . Я дійсно не можу придумати будь-який інший сценарій, коли часто потрібно запускати локальний файл, і якщо він не запускає його часто, він би не намагався задавати питання (він сказав, що це важко, не неможливо ) (2) не дуже, але можна передати аргументи в рецепті.
ihato

(1) Ну, мабуть, ми можемо погодитись, що мотивація ОП та обсяг його питання є незрозумілими. (2) Дякуємо за посилання.
G-Man каже: "Відновіть Моніку"

3

Щоб розширити відповідь Zanna про інтерпретаторів (вибачте, немає коментаря для коментаря): "інтерпретатор" для власних виконуваних файлів (aka binary файли ELF) - це динамічний завантажувач ( ld.so), але він, як правило, не розуміє потрібний синтаксис:

$ /usr/lib/ld-linux-x86-64.so.2 program
program: error while loading shared libraries: program: cannot open shared object file
$ /usr/lib/ld-linux-x86-64.so.2 ./program
<program is launched>

(також, якщо ви не посилаєтеся ld.soна свій шлях, вам все одно потрібно буде записати /)


Це специфічно для Linux, правда? Не могли б ви пояснити це докладніше, чому це працює? Я думав, що ядро ​​(Linux) буде робити аналіз і вирішувати, чи і як запустити бінарне, саме binfmt_miscдля цього потрібно.
phk

2
@phk Файл є специфічним для Linux, але концепція динамічного лінкера / завантажувача не є. Наприклад, FreeBSD має свою власну /libexec/ld-elf.so.1. У Linux це не так просто, як "вирішити, як запустити бінарний файл": binfmt_miscвизначає формат файлу за допомогою магічних чисел (ELF, скрипт shebang, CIL). Після цього binfmt_elfвикликається обробник. Розбирає заголовки та секції ELF; .interpрозділ містить шлях динамічного навантажувача; цей завантажувач запускається ядром, здійснює переміщення та стрибки на _start. У FreeBSD (не впевнений в інших) немає binfmt, але принцип +/- схожий.
березня 1717 року

1
@phk щодо того, чому це працює - ld.soне має .interpта є статично пов'язаним, а це означає, що інший динамічний посилання / завантажувач не потребує розв'язання зовнішніх символів і математики переміщення.
підписаний

ISTR Solaris також має щось еквівалентне цьому.
G-Man каже: "Відновіть Моніку"

3

Якщо нам дозволяють розпочати налаштування речей

mkdir -p ~/.local/bin
cat > ~/.local/bin/x << 'EOF'
#!/bin/sh
N="$1"
shift
exec "./$N" "$@"
EOF
chmod a+x ~/.local/bin/x

Більшість сучасних дистрибутивів вже включають ~ / .local / bin у $ PATH (додайте export PATH="$HOME/.local/bin:$PATH"до свого, ~/.profileякщо вашого немає). Потім ви можете використовувати x fileдля запуску ./file.

Не намагайтеся визначити .команду. Команда . scriptвже працює scriptу поточній оболонці. Це дозволяє scriptвизначити змінні середовища для поточної оболонки.


3
Я думаю, що тут може бути гарна пропозиція, але немає пояснення того, що робить щось із цього. Я міг би це розробити, але у недосвідченого користувача не було б жодного шансу.
IMSoP

Не потрібно переводити $ 1. Просто exec "$@".
reinierpost

$ (ln -s /bin/ls my-ls && exec my-ls) # bash: exec: my-ls: not found
sourcejedi

(1) Не потрібно shift $1; просто exec ./"$@". (2) Оскільки ви говорите про скрипт оболонки, радити людям не визначати .команду трохи безглуздо / оманливо , оскільки створити файл, який називається, неможливо .. (Можна і дуже недоцільно визначити функцію псевдоніму або оболонки під назвою ..)
Скотт

1

Якщо нам дозволяють робити помічникові сценарії, ви можете зробити помічника, який додає pwd до PATH, а потім запустіть

. pathhelper    #adds pwd to path
file            #now it can be run without ./

Це дозволяє уникнути додавання "." до шляху та забруднюючи ваш .profile кожним шляхом, який ви в певний момент можете щось запустити.

Ми можемо зробити цей підхід на крок далі, створивши помічника, який запускає нову оболонку із модифікованим PATH. Якщо він приймає каталог як параметр (використовуючи pwd за замовчуванням), він буде функціонувати так, як pushdредагує шлях. Можливо, вам доведеться пам’ятати, що будь-які зміни в інших змінних середовища будуть втрачені при виході з нижньої оболонки, але в тривалій оболонці ваша змінна PATH не збиватиметься з усіх. Залежно від ваших робочих процесів це може бути вигідним.

:outer shell prompt$; subshellpathhelper    # launches a subshell with modified PATH
: subshell prompt $ ; file                  # in the subshell it can be run without ./

Але я гадаю, що якщо ви хотіли запустити з ним, ви можете зламати, pushdі popdтому вони можуть внести ті самі зміни в шлях, не вносячи підзаголовок, які втратять інші зміни.

pushd --path ~/some/path/    # normal pushd plus adds target to path
file                         # it can be run without ./ until you popd

(Ви не можете зробити те ж саме, cdоскільки він не має аналога popd.)

Ви також можете створити виділену пару помічників, щоб просто натискати та висувати записи PATH. Те, що найкраще працює, залежить від моделей використання.


Насправді, ви можете зробити щось подібне cd, але це далі: Створіть файл, як .dircmds, і хак, cdщоб зробити команди, визначені ./.dircmdsнедоступними безпосередньо перед переключенням, і доступними відразу після переключення.
ShadSterling

-1

Ви можете використовувати . script.shсинтаксис до тих пір, поки сценарій, який ви хочете виконати, знаходиться в поточному каталозі.

Ви також можете префіксувати за допомогою інтерпретатора, наприклад, sh або bash. приклад:bash script.sh


8
. script.shзламається, якщо скрипт містить exit, має несподівані ефекти, наприклад, якщо він переглянув PATH "тимчасово"; він також працює лише для скриптів для вашої поточної оболонки
sourcejedi

@sourcejedi Що стосується того, що exitви можете помістити його всередині дужок, тобто підзаголовок, але правда, це все ще буде лише для сценаріїв в одній оболонці.
phk

Питання говорить "виконуваний файл". Вони не працюватимуть для двійкового виконуваного файлу; лише для сценарію. А ваш другий абзац дублює відповідь Занні .
Скотт

Ну, моє погано, я здебільшого виконую і баш-речі, тому я припускав, що ми говоримо про скриптики баш :)
UltimateByte

Не тільки для сценарію, але лише для сценарію Bash.
Оскар скаго
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.