.sh拡張子を指定しますか?


12

.sh拡張子なしでファイル名を指定するだけでファイルを実行するシステムと、名前と拡張子を必要とするシステムがあるのはなぜですか?私の場合、これらの指示に従って一連のコマンドを記述しようとしています。

現在、拡張子を指定していますが、コマンドを実行せずに実行できる.shことが望ましいでしょう。


4
.sh拡張機能として使用することは多くの状況で悪い習慣と見なされます:他のコマンドの名前の付け方に反して(実行しないls.elf)、しばしば誤解を招きます(でfoo.sh始まる場合、#!/bin/bash実行sh foo.shはそれが構築されたものとは異なるインタープリターで実行します) )、およびfoo.shPythonプログラムに書き換える場合、その拡張子を使用すると、今では紛らわしい名前を保持するか、それを呼び出すすべてのプログラムを書き換えるかを選択する必要があります。
チャールズダフィー

2
...それがどこであるのベストプラクティスは、シェルのライブラリである、とコマンドのない+xセット- foo.sh任意のPOSIXシェルに調達することができ、ライブラリが、さfoo.bashは、bashにソースすることができますfoo.kshなど、kshのに
チャールズ・ダフィー

回答:


39

混乱しています。この.sh拡張子は人間へのヒントにすぎず、システムがファイルを処理する方法にはまったく影響しません。Unix / LinuxはWindowsのSecrets.pdf.exe失敗を引き起こしませんでした。

入力するとfoo次のようになります。

  1. STDINSTDOUTおよびのリダイレクトSTDERRが設定されています。

  2. シェルは、内部ハッシュテーブルをチェックして、の$PATHエントリを既に知っているかどうかを確認しfooます。存在しない場合、シェルはのディレクトリを検索し、ファイル許可に実行ビットが設定されている$PATHと呼ばれるファイルを探しfooます。最初にfoo勝ちます。

  3. ファイルの最初の2バイトfooがの#!場合、次の文字列は実行するインタープリターの名前です。したがって#!/bin/bash、Bashスクリプトの#!/usr/bin/perl導入、Perlスクリプトの導入などが行われます。

  4. ファイルがで始まる場合\177ELF、それはバイナリ実行可能ファイルであり、ld.so起動します。

読むman execveman ld.so、より詳細な説明のために。


15
はい、LinuxではSecrets.pdfをダブルクリックできますが、実際には実行可能ファイルであるという名前からはわかりません;)
OrangeDog

1
@OrangeDogあなたが冗談を言っていることは知っていますが、実行可能ビット(chmod +x)がこれをほとんど解決していることを指摘しなければならない気がします。
-wchargin

3
@WCharginそれは、ファイルシステムの動作の良さ(たとえば、マウントされたネットワーク共有またはNTFSパーティションがxすべてのビットを楽観的に設定する可能性があります)およびファイルの出所(ディレクトリを制御するプロセスが許可を設定するようにだまされる可能性があります) 。だから、それはそれを緩和しますが、私はそれがそれを解決するとは言いません。
IMSoP

2
@WChargin、まだ、しかし、私は通常、ファイルマネージャーは実行可能ビットを表示しない、つまり拡張機能のような「人間へのヒント」がないという彼のポイントを考える。
ポールドレーパー

1
私はSecrets.pdf.exe常に愚かなhide file extension機能を無効にするため、間違ってクリックすることはありません
-phuclv

12

キーポイントはこれです:Unixライクなシステムでは拡張子は関係ありません。ファイル名は単なる名前であり、スクリプトまたはコンパイルされた実行可能ファイルを実行できるかどうかには影響しません。プログラマーは.sh、ファイルがシェルスクリプトまたは.pypythonスクリプト用であることを指定するために拡張子を追加できますが、Windowsとは異なり、unixは名前付けを気にせず、許可を気にします。

重要なのは、ファイルに付与された実行許可です。確認できるもの

ls -l /path/to/file

実行可能ファイルを実行する

スクリプトを実行するには、一般にいくつかの方法があります。

  • 現在のディレクトリがスクリプトと同じであり、スクリプトに実行権限がある場合は、そのように実行できます./my_script_name.カレントディレクトリを意味します。
  • 現在のディレクトリが異なり、スクリプトに実行権限がある場合、フルパスを指定して実行できます。 /home/user/bin/my_script_name

(上記の二つの方法が実行可能な権限セットを持つに依存している、ファイルがの一部であるか否かの$PATH変数は無関係であるの存在。#!ラインも重要、それなしで、それはスクリプトが開いている現在のシェルによって実行されます私が持っている場合。cshスクリプトをその行なしで、bashで実行しようとすると、./my_script.csh失敗します)

  • スクリプトが$PATH変数の一部であるディレクトリにある場合、名前を呼び出すだけでスクリプトを実行できます。chmodコマンドは/binフォルダー内にあるため、名前を入力するだけでコマンドラインで呼び出すことができます。/bin常に$PATH変数の一部です。この場合、実行可能権限とスクリプトの場所が重要です
  • インタープリターをコマンドとして、スクリプトを引数として指定します。このようにして、スクリプトはインタープリターへの入力ファイルとして機能します。
  • ファイルの調達。. filename.shまたはsource filename.shそれが直接コマンドラインに入力されたかのように、キーボード入力、すなわちだったかのようにスクリプトが扱われるようになります。この場合、実行権限と場所は関係ありません

インタープリターを使用して実行し、権限を実行する例#1

$-> ls -l abc.py                                                               
-rw-rw-r-- 1 xieerqi xieerqi 44 Apr 27 22:39 abc.py
$-> python abc.py                                                              
a
b
c

例#2、実行./可能アクセス権セット、shebang行セットで実行。

$-> cat abc.py                                                                 
#!/usr/bin/env python
for letter in 'a' 'b' 'c' :
   print letter
$-> ls -l abc.py
-rwxrwxr-x 1 xieerqi xieerqi 66 Apr 27 23:02 abc.py*
$-> ./abc.py                                                                   
a
b
c

例#3、シェバン行セットなしで実行(失敗、bashはpythonスクリプトを読み取れないため、シェバン行は現在のシェルをインタープリターと見なさない)

$-> cat abc.py                                                                 
for letter in 'a' 'b' 'c' :
   print letter
$-> ./abc.py                                                                   
./abc.py: 2: ./abc.py: Syntax error: word unexpected (expecting "do")

例#4、実行可能権限が設定されているスクリプトを実行して、$PATH変数の一部であるフォルダーをフォームに設定する

#  /home/xieerqi/bin is part of my path variable
$-> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/microchip/xc16/v1.25/bin:/opt/microchip/xc32/v1.40/bin:/opt/microchip/xc8/v1.35/bin:/home/xieerqi/bin:/home/xieerqi/bin/sh

$-> # current directory is /home/xieerqi
$-> pwd
/home/xieerqi
$-> # move the file to ~/bin
$-> mv ~/abc.py ~/bin/abc.py
$-> # now I can run it just by calling the name
$-> abc.py
/home/xieerqi/bin/abc.py: 2: /home/xieerqi/bin/abc.py: Syntax error: word unexpected (expecting "do")
$-> # Syntax error because again, no interpreter specified.                    
$-> # must add #!/usr/bin/env python
$-> vi /home/xieerqi/bin/abc.py          
$-> # after adding the line with vi text editor, we can run
$-> abc.py                                                                     
a
b
c

例#5、拡張機能の削除は、拡張機能は重要ではないため実行されますが、アクセス許可があり、$PATH次の一部です:

$-> mv ~/bin/abc.py  ~/bin/abc                                                 
$-> abc
a
b
c

コマンドを実行すると、この「-rwxr-x ---」が表示されます。値に何を読み取らせて、どのように変更できますか?
フィリップカークブライド

または、単に「filename.sh」の名前を「filename」に変更する必要があると言っていますか?
フィリップカークブライド

1
@PhilipKirkbride名前は関係ありません。どのようにコマンドを実行しますか?それはどこにある ?ディレクトリはあなたの一部PATHですか?
セルギーコロディアズニー

@PhilipKirkbride答えをより明確にするために、すぐに答えを拡大します。
セルギーコロディアズニー

1
man chmodアクセス許可を設定する方法を見てください
ニックマーティン

6

ここですでに良い説明があります。理想的には、実行可能ファイルにファイル拡張子を使用しないでください。

通常、比較的簡単なことを行う必要があり、小さなシェルスクリプトから始めます。時間が経つにつれて、スクリプトに機能を追加し始め、メンテナンス不能になるか、シェルスクリプトで簡単に達成できない機能が必要になるまで、このシェルスクリプトを別の言語で書き換えることを考えます(python 、perl、...?)。

通常、ゼロから書き直すことはエラーと見なされますが、通常はそれほど大きくないか、多くの機能を備えているため、スクリプトでは意味があります。しかし、最初のシェルスクリプトの機能とparams / flagsを維持しながら、他の言語でゼロから書き直すことが可能であると仮定しましょう。

このスクリプトのユーザーは、この言語の変更を意識する必要はありません。同じコマンドを実行し続け、機能し続けます。

スクリプトに名前が付けられている場合は、do-something.sh引き続き存在できますがdo-something.sh、現在は(たとえば)pythonで記述されているため、最初のヒントは完全に誤解を招くものです。


4

拡張子なしでファイルを実行するには、通常多くのことを行う必要はありません。(bashスクリプトの場合)最初の行に適切なシェバン行があることを確認してください:

#!/bin/bash

次に、システムのファイルを実行可能にする必要があります

chmod 755 yourfilename

これはchmod +x yourfilename簡単に説明されている数字を使用するのと同じです。

これは、追加された8進数の数字のトリプルであり、最初の数字はユーザーを表し、2番目はグループを表し、3番目は他を表します。詳細については、こちらを参照してください

また、スクリプトと同じディレクトリにいる場合は、次の./ように使用することを忘れないでください。

./yourfilename

これを試してみました。残念ながら、元の結果との違いはありません。
フィリップカークブライド

@PhilipKirkbrideは、修正された答えを見て、これが適切にいくつかの光を放つことを期待しています。
Videonauth

0

.sh接尾辞は実際に邪魔になることがあります。それを実行するには、動作しないmyscriptの代わりにmyscript.shを入力する必要があるからです。.sh接尾辞なしで単に「myscript」と呼ぶ方が良いです。「file」コマンドをすばやく使用すると、バイナリ実行可能ファイル(LinuxではELF形式)か、シェルスクリプト、またはその他の種類のスクリプトかがわかります。

QDOS(Quick and Dirty Operating System、後にIBMによってmirosoftが海賊版にされ、違法に販売された後に「DOS」に名前が変更されました)およびWindowsを含むCP / Mの他の安価なリッピングは、これらのシステムにはないため、これらすべてを混ぜ合わせますファイルの実行許可など。これにより、過去30〜40年で無数のセキュリティ問題が発生しています。実際、ほんの数分前に、ブービートラップされたzipファイルがMYPICTURE.JPG.zipに名前変更されたジャンクメールをいくつか受け取りました。

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