./testではなく.testとして実行


26

私が実行可能ファイルと同じフォルダにいると仮定すると、実行するにはこれを入力する必要があります。

./file

入力するのは難しい/ので、入力する必要/はありません。

ファイルを実行する簡単な方法はありますか?次のような単純な構文が理想的です。

.file

または何か他のものが、/そこに文字を挿入するよりも簡単です。

おそらく、/binディレクトリに何かを入れたり、インタープリターのエイリアスを作成したりする方法があります。

p file

9
xmodmapを使用して別のキーと交換するか?だから、少なくとも、それが入力する方が簡単です
ガイ

26
補足として、これは主にディレクトリセパレータとしてUnixで広く/使用れています。簡単に入力する方法を見つけた方がよいでしょう。
クリリス

7
@RossPresserこの質問は以来ほとんど意味がありません。ファイルの先頭にある./は、初心者が知っておくべき技術的な理由から、まったく異なる2つの意味です。/大多数の人にとってタイプすることは難しくありません。OPがこれを妨げる負傷がある場合、代替キーボードレイアウトを検討する必要があり/ます。
JFA

1
@JFA大陸ヨーロッパと南アメリカで使用されているキーボードレイアウトの大半は/、けがをしなくても入力が比較的難しいシフト7を採用しています。
nitro2k01

6
編集履歴:「なぜカントネットワークインターフェイスは、単にポート22でssh経由でリモートホストを介してすべてのインターネットクエリを作成するように指示され、」ಠ_ಠ
デレク・朕會功夫

回答:


35

それは「危険」かもしれませんが、あなたはただ持つことができます。PATHで。

他の人で言われているように、これは危険な場合があるので、常に確認してください。先頭ではなくPATHの最後にあります。


1
それがどのように「危険」であるかを実際に見ないでください:私の道はLinuxのずっと前からその方法であり、わずかな問題を引き起こしたことはありません。
jamesqf

21
@jamesqf誰でもcd書き込み可能なディレクトリに移動し、パスにないコマンドを使用しようとすると、誰かがそのパスに書き込んだのと同じ名前で(悪意のある可能性がある)実行可能ファイルを実行する可能性があるため、危険です。.パスの先頭に配置すると、これはさらに悪化します。その場合、そのディレクトリでls呼び出すと、悪意のある実行可能ファイルが実行されますls
バイト化された

2
上記の理由により、これを避けてください。pコマンドが良いだろう。
グイド

11
@jamesqfそれが「あなたの」システムであり、あなただけがそれを使用するとき、それはそれほど悪くありません。問題はマルチユーザーシステムで発生します(そして、長年にわたって多くのUnix管理者をつまずかせてきました)。の.早い段階で、PATH悪意のあるユーザーが行う必要があるのはls、ディレクトリに偽のコマンドをドロップし、管理者に「奇妙なものを見る」ように説得し、ルートアクセス権を取得することだけです。
TripeHound

1
良い解決策ですがtest、質問のタイトルのように、ファイルの名前がたまたま機能しない場合は機能しません(testシェルはビルトインであり、おそらく$PATH既にあなたのどこかに存在するからです)。
yellowantphil

71

../少なくとも最新のBashシェルでは自動補完(入力.して押すTab)が行われるため、複雑なまたは安全でない(PATH変更などの)ソリューションを使用する必要はありません。

自動補完されない場合は、「bash-completion」パッケージをインストールする必要があります。


本気ですか?.複数の補完候補があります:(.現在のディレクトリ)、..(親ディレクトリ)、.コマンド(bashは非標準のエイリアスsourceを提供します)、および存在するすべてのドットファイル。bash-completionパッケージはこれを無視するかもしれません。私はそれをひどく迷惑に感じます(たとえば、makeコマンドラインでディレクトリ名をタブ補完することができなくなり、一般に暗黙のルールでいっぱいのmakefileでひどいです)。
R ..

3
試しましたが、はい、この方法で自動補完を行います。ほとんどすべての場合、それは通常のユーザーが望むものです:実行可能なドットファイルを見たことはないと思います。サブディレクトリで何かを実行することは親ディレクトリで何かを実行するよりもはるかに一般的であり、IMOはそれを行いますmakeターゲットを見つけるのは非常に良い仕事です。
l0b0

bash 3.2では、オートコンプリートは行われません。これはbash 4の新機能ですか?
カリモ

2
@Calimo bash-completionの最近のバージョンでは新しい可能性が高いです。それは根本的な変化とはほど遠い。
l0b0

42

または..おそらくインタプリタにbashrcファイルのエイリアスを与えてから単純に

   p  file

そのような関数を書くことは可能です:

p() {
 ./"$@"
}

あなたの~/.bashrc。その後、のp app arguments代わりに実行できるようになります./app arguments。このソリューションは、スクリプトやバイナリなど、あらゆるタイプの実行可能ファイルに対して機能します。

"$@"関数に渡された引数の適切に引用符で囲まれたリストに展開し(グロブまたは変数展開からすべての特殊文字を保持)、@ Scottが指摘したように、残りの部分を保持して、それらの最初の1つに付加するのにbash十分賢い./です。


別のコマンドでアプリを実行することは一般的ではありませんstrace -f p appが、システムコールが行われた$(which time) p appことを確認したり、所要時間を確認したりします。 p私が考案したこれら2つの特定の例では、実行可能スクリプトがより適切に機能するためです。おそらくこのような理由で、フルパスを要求する点で異なりますがldd p app、どちらのソリューションもで動作しません。ldd
sourcejedi

はい、誰にも見えない方法で置換するp app args./app args、何らかの種類のプリプロセッサを介してシェル入力をパイプする必要があり、意図しない場所で置換が発生するとあらゆる種類の楽しみが発生します:)
aitap

1
この場合、引用符はありません$@か?それ以外の場合は、1つの大きな引数をプログラムに渡すだけです。
Kroltan

7
@Kroltan No. $@は配列です。内"で展開すると、各パラメーターは個別の単語に展開されます。$*あなたが考えているように振る舞います。
8bittree

3
あなたはこれを不必要に複雑にしたと信じています、そしてそれp() { ./"$@"; }があなたが必要とするすべてです。
スコット

11

あなたは入れることができ.、あなたに$PATH例を追加することでPATH=$PATH:.、あなたに/etc/profileあなたが実行することができ、このようfile書面でちょうどfileそれはあなたのパス(例えば、いくつかの他のフォルダ内にある場合を除き、/usr/bin/)。これは一般に良い考えではないことに注意してください。

なぜ悪いのか:ディレクトリの内容を完全に信頼していない状況にあるとしましょう-どこか危険なところからダウンロードしたので、実行する前に調査したい、またはあなたがシステム管理者であるユーザーは、ホームディレクトリなどを検索します。ディレクトリを一覧表示したいので、lsと入力しようとしますが、おっと、タイプミスをして、代わりにslと入力します。この悪意のあるディレクトリの作成者はこれを予期して、「rm -rf --no-preserve-root /」(またはルートキットのインストールのようなもっと悪意のあるもの)を実行する「sl」と呼ばれるシェルスクリプトを置きました。

(説明をありがとう@Muzer)


13
私は完全に同意しますが、おそらくこれが良いアイデアではない理由を正確に説明しているでしょう。
ymbirtt

16
なぜ悪いのか:ディレクトリの内容を完全に信頼していない状況にあるとしましょう-どこか危険なところからダウンロードしたので、実行する前に調査したい、またはあなたがシステム管理者であるユーザーは、ホームディレクトリなどを検索します。ディレクトリを一覧表示したいので、lsと入力しようとしますが、おっと、タイプミスをして、代わりにslと入力します。この悪意のあるディレクトリの作成者はこれを予期して、「rm -rf --no-preserve-root /」(またはルートキットのインストールのようなもっと悪意のあるもの)を実行する「sl」と呼ばれるシェルスクリプトを置きました。
ミューザー

2
現在のディレクトリが$ PATHの先頭にある場合、その代わり、攻撃者はただのlsや他の一般的なコマンドをオーバーライドすることができることを説明するフォートワース
DélissonJunio

@Muzer Huuuge tinfoil hatsはこちら。
ソンブレロチキン

4
@GillBates実際の、潜在的に悪意のあるユーザーに対処しなければならないシステム管理者、または生涯にわたって疑わしいアーカイブを分析する誰かとして注意する必要があるようなものです。どちらも当てはまらない場合は、同意します。ただし、状況がいつ変わるかわからない、これらの仕事の1つを得る、そして安全でない行動に頼るように自分を訓練したことに対して果てしなく自分自身を呪うので、入るのは良い習慣ではないと思います。 )
ミューザー

10

たとえば、インタプリタを呼び出すことができます

bash test

この場合、スクリプトには、シバン行(例#!/bin/bash)も実行可能ビットもない場合でも実行されます。それを実行するには、正しいインタープリターを知っている必要があります。ファイルのシェバン行を最初に読んで、正しいインタープリターを呼び出すようにしてください。たとえば、シェバン行に

#!/usr/bin/env python3

あなたは電話します

python3 test

7
インタプリタはコードを解釈するだけで、バイナリファイルは実行しません
Mc Kernel

おそらくインタープリターにbashrcファイルのエイリアスを与えることができるため、この答えはやや論理的です。

5
@McKernel良い点インタプリタがある場合、それだけではないコンパイルされた実行ファイルのため、動作します
Zanna

2
コンパイルされた実行ファイルのための通訳があります:/lib/ld.so
ドミトリーKudriavtsev

7

私の知る限り、envパスにfileを含めない限り、それを実現する方法はないので、次のように入力するだけで実行できます。 file

.file別のファイル名であるため、機能しません。というファイルであり、では.fileありません./file

おそらく英語ではないレイアウトだから、スラッシュはタイプしにくいかもしれませんね。その場合、それは私にも起こるので、WindowsでAlt + Shiftを押してキーボードレイアウトを英語に頻繁に切り替えます(私はsshのLinuxを使用しています)


7

に追加.することを提案しましたPATH。これは、世界で書き込み可能なディレクトリに配置された悪意のあるプログラムを誤って実行する危険性があるため、危険です。あなたはあなただけで所有し、書き込み可能であることを、いくつかのディレクトリで実行可能なプログラムを持っている場合しかし、それは(かなり安全ですか?)安全で入れて、それらのディレクター(IES)のPATH次のような行を追加することで、

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

あなたの~/.bashrcファイルに。もちろん、これはファイルシステムのどこからでもそれらのディレクトリの1つからプログラムを実行できることを意味します。たとえば、cd /etcと入力fooすると、が実行され~/dev/myprog1/fooます。これには、複数のディレクトリで同じ名前のプログラムを使用できないという小さな欠点があります。特に、とのfoo 両方~/dev/myprog1で呼び出されるプログラムがある場合~/dev/myprog2、パスを指定しない限り、2番目のプログラムを実行することはできません。同様にあなたが持っている場合~/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はシェル組み込みコマンドであるため、実行可能ファイルの名前は避けてください。パスまたは他のトリックを指定するだけで、その名前でプログラムを実行できます。


別の方法として、レシピを作成し(Makefileを使用する場合)、make gizmoまたはを実行することもできmake gonzoます。
いはと

申し訳ありませんが、それが質問や私の答えにどのように関係しているか理解できません。あなたはOPが作成することを示唆しているMakefileのアクション、各ディレクトリになるようにmake gizmoすることで、エンドを実行していますか gizmo?(1)それはp、最初にaitapによって実装され、スコットによって改良された、質問で提案された関数と同じことを行う厄介な方法のようです。(2)そのように引数を渡すことができますか?にmake gizmo arg1 arg2相当するISTM make gizmo; make arg1; make arg2
G-Manが「Reinstate Monica」と言う

1
(1)おそらく私の仮定は間違っているが、OPがすべてのディレクトリで使用./することを避けたいのかどうかははっきりしない。私の考えでは、彼は何かを開発しており、作成されたプログラムを頻繁に実行する必要があります。ローカルファイルを頻繁に実行する必要があり、頻繁に実行していない場合、彼は質問することを気にしません(彼は不可能ではなく難しいと言いました)(2)そうではないが、レシピで引数を渡すことができます。./file
イハト

(1)まあ、私はOPの動機と彼の質問の範囲が不明確であることに同意できると思います。(2)リンクをありがとう。
G-Manが「Reinstate Monica」と言う

3

インタプリタに関するZannaの答えを拡張するために(ごめん、コメントの担当者はいません):ネイティブ実行可能ファイル(別名バイナリ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パスにシンボリックリンクしない限り、/s を書く必要があります)


これはLinux固有ですよね?これをもっと説明してください、なぜこれが機能するのですか?(Linux)カーネルが解析を行い、バイナリを実行するかどうか、および実行方法を決定すると思いbinfmt_miscました。それが目的です。
phk

2
@phkファイルはLinux固有ですが、動的リンカー/ローダーの概念はそうではありません。たとえば、FreeBSDには独自のがあり/libexec/ld-elf.so.1ます。Linuxでは、「バイナリの実行方法を決定する」ほど簡単ではありません。binfmt_miscマジックナンバー(ELF、シバンスクリプト、CIL)によってファイルのフォーマットを検出します。その後、binfmt_elfハンドラーが呼び出されます。ELFヘッダーとセクションを解析します。.interpセクションには、ダイナミックローダーのパスが含まれます。このローダーはカーネルによって起動され、再配置を行い、にジャンプし_startます。FreeBSD(他の人についてはわかりません)にはbinfmtはありませんが、原則は+/-に似ています。
ベーコンドロップ

1
@phkがこれが機能する理由- ld.so持たず.interp、静的にリンクされているため、別の動的リンカー/ローダーが外部シンボルを解決して再配置計算を行う必要がないことを意味します。
ベーコンドロップ

ISTR Solarisにもこれと同等のものがあります。
G-マンは「元に戻すモニカ言う

3

構成を開始できる場合

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

最新のディストリビューションのほとんどは、$ PATHに〜/ .local / binを既に含んでいます(含ま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

ヘルパースクリプトの作成が許可されている場合は、PATHにpwdを追加するヘル​​パーを作成してから実行できます。

. 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 ./

しかしpushdpopdそれで実行したい場合は、ハッキングでき、他の変更を失うサブシェルを作成せずにパスに同じ変更を加えることができると思います。

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

質問は「実行可能ファイル」と言います。これらはバイナリ実行可能ファイルでは機能しません。スクリプトのみ。そして、2番目の段落はZannaの答えを複製します
スコット

まあ、私の悪い、私は主にbashのものを実行して開発しているので、bashスクリプトについて話していると仮定しました:)
UltimateByte

スクリプトだけでなく、Bashスクリプトも対象です。
オスカースコグ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.