Linux中的二進制可執行文件和腳本可執行文件及Shebang

Linux中的二進制可執行文件和腳本可執行文件及Shebang

二進制可執行文件

我們知道,一個C程序經過預處理、編譯、匯編、鏈接就會得到一個二進制可執行文件,這種文件在Linux中叫做ELF文件。比如我們有一個C源代碼hello.c

#include <stdio.h>int main(int argc, char** argv){printf("Hello !\n");
}

我們編譯得到 hello 文件,并用file命令可以查看到生成的二進制可執行文件的信息:

gcc hello.c -o hello
file hello
# 輸出:
# hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=cf2738fd1715f096d4b0e0e4b264146b78b454b1, not strippe

確實是ELF文件,我們可以直接執行它:

./hello
# 輸出:
# Hello

這是我們常見的,可以理解的,鏈接后的可執行文件就是可以直接運行,就像我們在Windows上雙擊打開一個exe文件那樣自然。那么,腳本可執行文件又是怎么一回事呢?

腳本可執行文件及Shebang

腳本可執行文件也可以像運行二進制可執行文件那樣來直接運行它。我們知道shell、python等屬于腳本語言。令我們好奇的是,腳本程序如 train.py 等看上去只是一個文本文件,為什么也能直接被執行呢 ?

我們知道,想要運行一個腳本文件,我們需要指定一個解釋器。通常,我們有兩種方式來指定腳本文件的解釋器:

  1. 在命令行中指定,如bash run.shpython train.py等。
  2. 通過文件中的第一行Shebang指定。在腳本文件的頭上,通常會有一行Shebang:#!。比如:#!/bin/bash#!/home/song/bin/python等。

Shebang通常出現在類Unix系統的腳本中第一行,作為前兩個字符。在Shebang之后,可以有一個或數個空白字符,后接解釋器的絕對路徑用于指明執行這個腳本文件的解釋器。在直接調用腳本時,系統的程序載入器會分析 Shebang 后的內容,將這些內容作為解釋器指令,并調用該指令,將載有 Shebang 的文件路徑作為該解釋器的參數,執行腳本,從而使得腳本文件的調用方式與普通的可執行文件類似。例如,以指令#!/bin/sh開頭的文件,在執行時會實際調用 /bin/sh 程序(通常是 Bourne shell 或兼容的 shell,例如 bash、dash 等)來執行。

由于 # 符號在許多腳本語言中都是注釋標識符,這既是偶然,也是必然。Shebang 的內容會被這些腳本解釋器自動忽略。 在 # 字符不是注釋標識符的語言中,例如 Scheme,解釋器也可能忽略以 #! 開頭的首行內容,以提供與 Shebang 的兼容性。

實際上,#!兩個字符的ASCII碼是兩個magic字符,當類UNIX操作系統看到一個文件以這兩個字符開頭,會將這個文件當做是可執行文件,并且按照其后的解釋器來執行它(需要有執行權限)。這時,操作系統實際上加載的是 #! 后面跟的那個二進制文件(即解釋器),然后將腳本文件的文本內容作為參數傳給這個二進制文件。這一點可以通過觀察腳本可執行文件運行使得strace結果中的execve來驗證。

Shebang的一些具體用法和注意事項:

  1. 如果腳本文件中沒有#!這一行,那么執行時會默認采用當前Shell去解釋這個腳本(即:SHELL環境變量)。
  2. 如果#!之后的解釋程序是一個可執行文件,那么執行這個腳本時,它就會把文件名及其參數一起作為參數傳給那個解釋程序去執行。
  3. 如果#!指定的解釋程序沒有可執行權限,則會報錯 bad interpreter: Permission denied。如果#!指定的解釋程序不是一個可執行文件,那么指定的解釋程序會被忽略,轉而交給當前的SHELL去執行這個腳本。
  4. 如果#!指定的解釋程序不存在,那么會報錯 bad interpreter: No such file or directory。注意:#!之后的解釋程序,需要寫其絕對路徑(如:#!/bin/bash),它是不會自動到環境變量PATH中尋找解釋器的。要用絕對路徑是因為它會調用系統調用execve,這可以用strace工具來查看。
  5. 腳本文件必須擁有可執行權限。可通過chmod +x [filename] 來添加可執行權限。
  6. 當然,如果你使用類似于 bash test.shpython train.py這樣的命令來執行腳本,那么#!這一行將會被忽略掉,解釋器當然是用命令行中顯式指定的解釋器。

我們來試一下,先創建一個py文件world.py,并直接寫入為:

print('World !')

我們可以通過在命令行指定python解釋器來運行,就像我們一直做的那樣:

python world.py
# 輸出:
# World !

但是,當我們想像運行二進制可執行文件那樣來運行它

./world.py
# 輸出:
# -bash: ./world.py: Permission denied

首先會受到一條沒有執行權限的命令,如上。這很正常,因為我們創建的時候它是一個文本文件嘛。我們通過 chmod 來使得它可執行,并再次嘗試運行它:

chmod +x world.py
./world.py
# 輸出:
# ./world.py: line 1: syntax error near unexpected token `'World !''
# ./world.py: line 1: `print('World !')'

問題出現了,和我們之前討論的一樣,由于我們沒有通過Shebang來指定腳本的解釋器,系統默認用了Shell來解釋,那我們的python語法自然是不對的。那這時,想要像運行二進制可執行文件那樣去運行它,必須請出我們的Shebang來幫忙在文件內指明解釋器的絕對路徑。更改world.py 為:

#!/home/song/anaconda3/envs/JJ_env/bin/python
print("World")

這時我們再來運行:

./world.py
# 輸出:
# World !

就可以了。我們還可以通過 file 命令再來看一下 world.py 的文件信息:

file world.py
# 輸出:
# world.py: a /home/song/anaconda3/envs/JJ_env/bin/python script, ASCII text executable

我們看到該文件是一個ASCII text executable,即 ”文本可執行文件“。不同于ELF二進制可執行文件,但也是可執行文件。也就是說,在Linux的世界中,可執行文件不只有ELF一種。

另外,由于Linux系統對后綴名并不嚴格要求,我們可以直接將world.py改為world,這樣也是可以的,然后就可以通過將world這個腳本可執行文件放到PATH環境變量下,從而將world直接作為一個命令來使用啦!具體可參考筆者另一篇介紹Linux常用環境變量的博客。

總結

總結一下:Linux中除了ELF二進制可執行文件之外,還有腳本可執行文件,要想讓腳本可執行文件直接像二進制可執行文件一樣運行,而不需在命令行中指定解釋器,需要在腳本文件頭通過Shebang !#來指定解釋器的絕對路徑。Shebang的一些具體的注意事項在上文中已經指出。另外,通過將可執行文件(二進制、腳本都可)添加到PATH環境變量的可執行文件搜索目錄下,可將在命令行中通過命令來直接使用這些可執行文件。

Ref:

https://blog.csdn.net/u012294618/article/details/78427864

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532732.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532732.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532732.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pe能用的固態硬盤測試軟件,通用pe工具箱教你如何讓硬盤4K對齊

昨天小編教大家如何查看電腦硬盤是否4K對齊&#xff0c;馬上就有讀者告訴小編&#xff0c;查看電腦硬盤是否4K對齊的方法學到了&#xff0c;那么我使用的固態硬盤如何做到4K對齊呢&#xff1f;問的好啊&#xff01;現如今用戶對電腦硬件的要求是越來越高。很多用戶都不僅僅滿足…

[2020-ECCV]PIPAL-a Large-Scale Image Quality Assessment Dataset for Perceptual Image Restoration論文簡析

[2020-ECCV] PIPAL: a Large-Scale Image Quality Assessment Dataset for Perceptual Image Restoration 論文簡析 論文&#xff1a;https://arxiv.org/abs/2007.12142 代碼及數據集&#xff1a;https://github.com/HaomingCai/PIPAL-dataset 概述 本文認為隨著圖像重建&…

郫都區計算機老師周俊老師,教師節,帶你走進郫都教師背后的故事

點擊“郫都教育”關注我們&#xff1a;)有這樣一群人“師者&#xff0c;所以傳道&#xff0c;授業&#xff0c;解惑也”是他們奉獻一生的事業“隨風潛入夜&#xff0c;潤物細無聲”是他們培養英才的責任“春蠶到死絲方盡&#xff0c;蠟炬成灰淚始干”是他們追求終生的信仰值此第…

(2021) 18 [代碼講解] 可執行文件

(2021) 18 [代碼講解] 可執行文件 南京大學操作系統課蔣炎巖老師網絡課程筆記。 視頻&#xff1a;https://www.bilibili.com/video/BV1HN41197Ko?p18 講義&#xff1a;http://jyywiki.cn/OS/2021/slides/C8.slides#/ 背景 回顧 程序 狀態機 狀態機執行 狀態機上的路徑狀…

如何學習計算機思維,劉康平:為什么我們每個人都應該學習計算思維?

不久前&#xff0c;微軟亞洲研究院資深學術合作經理劉康平應邀在“造就”做了演講&#xff0c;以下為演講節選&#xff0c;由“造就”授權轉載。劉康平 微軟亞洲研究院資深學術合作經理以中國象棋為例&#xff0c;在這樣一個棋局上&#xff0c;你怎么用最快的方式找到「將」和「…

鏈接與加載-NJU-JYY

(2021) 19 [代碼講解] 從零實現動態加載 南京大學操作系統課蔣炎巖老師網絡課程筆記。 視頻&#xff1a;https://www.bilibili.com/video/BV1N741177F5?p15 講義&#xff1a;http://jyywiki.cn/OS/2021/slides/C9.slides#/ 背景 回顧&#xff1a; ELF可執行文件 只要能完成…

計算機械功的公式,機械功率計算公式

初中物理公式物理量(單位) 公式 備注 公式的變形速度V(m/S) v S /t (S:&#xff1a;路程&#xff1b; t&#xff1a;:時間 )重力G(N) Gmg (m&#xff1a;質量&#xff1b;g&#xff1a;9.8N/kg或者10N/kg)密度ρ(kg/m3) ρ m&#xff1a;質量/V&#xff1a;體積 (m&#xff1a;…

饑荒聯機自建服務器有什么用,聯機版饑荒使用專用服務器的好處 | 手游網游頁游攻略大全...

發布時間&#xff1a;2016-02-15存檔保存位置是?很多玩家對此并不是很了解,不過別著急喲,下面99單機小編就為你帶來高玩分享的相關技巧心得攻略,希望大家能喜歡. 聯機版的存檔與單機版是不同的,由于聯機版饑荒建 ...標簽&#xff1a;游戲資訊 攻略秘籍發布時間&#xff1a;201…

(2021) 26 [持久化] 持久數據的可靠性:RAID和journaling

(2021) 26 [持久化] 持久數據的可靠性&#xff1a;RAID和journaling 南京大學操作系統課蔣炎巖老師網絡課程筆記。 視頻&#xff1a;https://www.bilibili.com/video/BV1HN41197Ko?p26 講義&#xff1a;http://jyywiki.cn/OS/2021/slides/16.slides#/ 背景 回顧 文件系統 …

計算機-p命令,OD(電腦命令)_百度百科

od 命令用途是以指定格式顯示文件。常見的文件為文本文件和二進制文件。此命令主要用來查看保存在二進制文件中的值。比如&#xff0c;程序可能輸出大量的數據記錄&#xff0c;每個數據是一個單精度浮點數。這些數據記錄存放在一個文件中&#xff0c;如果想查看下這個數據&…

Linux下編譯、鏈接、加載運行C++ OpenCV的兩種方式及常見問題的解決

Linux下編譯、鏈接、加載運行C OpenCV的兩種方式及常見問題的解決 在Linux下安裝完OpenCV C之后&#xff08;還沒有安裝的讀者請參考Ubuntu 18.04 安裝OpenCV C&#xff09;&#xff0c;本文將探索Linux下編譯、鏈接C OpenCV的兩種方式&#xff0c;并且給出筆者在初次嘗試時遇…

win10無法檢驗服務器出示的ssl證書,win10系統網站啟用ssL安全證書的操作方法

win10系統網站啟用ssL安全證書的操作方法?很多win10用戶在使用電腦的時候&#xff0c;會發現win10系統網站啟用ssL安全證書的的現象&#xff0c;根據小編的調查并不是所有的朋友都知道win10系統網站啟用ssL安全證書的的問題怎么解決&#xff0c;不會的朋友也不用擔心&#xff…

Linux下構建自己的C++共享庫并配合pkg-config生成鏈接選項

Linux下構建自己的C共享庫并配合pkg-config生成鏈接選項 本文將以C鏈表的新建、打印操作為例構建自己的共享庫&#xff0c;并在實際調試代碼時嘗試使用。我們在做數據結構題時經常需要將鏈表打印出來看一下結果&#xff0c;但是并沒有一種庫函數可以讓我們直接調用來打印自己的…

webkitlineclamp css3,-webkit-line-clamp

無標題文檔static&#xff1a;對象遵循常規流。top&#xff0c;right&#xff0c;bottom&#xff0c;left等屬性不會被應用。 relative&#xff1a; 對象遵循常規流&#xff0c;并且參照自身在常規流中的位置通過top&#xff0c;right&#xff0c;bottom&#xff0c;left屬性進…

Linux內核初探

Linux內核初探 內核的組成部分 kernel&#xff1a;內核核心文件&#xff0c;一般為bzp_w_picpath&#xff0c;經過壓縮處理的鏡像文件&#xff1b;通常內核核心文件保存在/boot/目錄下&#xff0c;名稱為vmlinuz-version-release kernel object(ko)&#xff1a;內核對象&…

Nplayer本地文件拷到服務器,手把手教你簡易NAS構建,手機/平板/智能電視隨意調取,家庭存儲云共享,有了自己的網絡云盤后再也不用擔心容量不夠了!...

之前嫌鍵盤俠煩&#xff0c;寫這些也沒意義所以把賬號注銷了文章刪除了&#xff0c;現在想了想我抗吧12級老蛆還噴不過這幫小兔崽子&#xff1f;換了skt.ruo穢土轉生&#xff0c;求噴子和我在各評論對線。特別是匿名dog見一個懟死一個。下面是之前號寫的內容原文 -#簡介NAS全稱…

gdb 入門

gdb 入門 簡介 gdb是GNU開源組織發布的一個強大的Linux下的程序調試工具。 一般來說&#xff0c;GDB主要幫助你完成下面四個方面的功能&#xff1a; 1、啟動你的程序&#xff0c;可以按照你的自定義的要求隨心所欲的運行程序。 2、可讓被調試的程序在你所指定的調置的斷點…

視頻監控系統中的平臺服務器,【視頻監控主機 網絡視頻集中管理平臺服務器】 - 太平洋安防網...

完善的管理功能管理系統內所有設備的接入及設備權限。設備狀態監視。系統資源及用戶權限分配及系統搶權管理。電子地圖。實現系統內視頻流的管理和轉發控制。可通過WEB遠程管理。強大的報警事件管理功能系統具備完善的報警及處理功能&#xff0c;能根據預先編寫事件 處理預案對…

Linux下的CUDA多版本管理

Linux下的CUDA多版本管理 關于CUDA、cuDNN等的簡介和安裝可參考&#xff1a;顯卡、顯卡驅動、CUDA、CUDA Toolkit、cuDNN 梳理。 CUDA多版本 有時我們會在一臺機器上同時看到多個版本的CUDA&#xff0c;比如nvcc -V和nvidia-smi的輸出就可能會不同&#xff1a; 在我們實驗室…

電腦顯示無法連接sql服務器,他人的電腦為什么無法連接我電腦上的sql sever服務器...

如果SQL2005連接不上&#xff0c;并且服務器上所有與防火相關的東西都關閉了&#xff0c;還是連接不上。進行如下操作:一、為 SQL 啟用遠程連接1. 單擊“開始”&#xff0c;依次指向“程序”、“Microsoft SQL Server 2005”和“配置工具”&#xff0c;然后單擊“SQL Server 外…