<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么執(zhí)行自己的程序要在前面加./

          共 3598字,需瀏覽 8分鐘

           ·

          2020-08-29 11:34

          前言

          在Linux中,我們執(zhí)行內(nèi)置命令時,直接輸入命令名稱即可,如:

          $?mv?a?b?#將a重命名為b

          而在執(zhí)行自己寫好的程序時,卻要帶上./,例如:

          $?hello
          hello:?command?not?found
          $?./hello
          hello?world

          這是為什么呢?它們有什么區(qū)別呢?

          shell是如何運行程序的

          在說明清楚問題之前,我們必須了解shell是如何運行程序的。首先我們必須要清楚的是,執(zhí)行一條Linux命令,本質(zhì)是在運行一個程序,如執(zhí)行l(wèi)s命令,它執(zhí)行的是ls程序。那么在shell中輸入一條命令,到底發(fā)生了什么?如果沒有給出當前路徑或絕對路徑,它會經(jīng)歷哪幾個查找過程?

          alias中查找

          alias命令可用來設(shè)置命令別名,而單獨輸入alias可以查看到已設(shè)置的別名:

          $?alias
          alias?egrep='egrep?--color=auto'
          alias?fgrep='fgrep?--color=auto'
          alias?grep='grep?--color=auto'
          alias?l='ls?-CF'
          alias?la='ls?-A'
          alias?ll='ls?-alF'
          alias?ls='ls?--color=auto'

          如果這里沒有找到你執(zhí)行的命令,那么就會接下去查找。如果找到了,那么就會執(zhí)行下去。

          內(nèi)置命令中查找

          不同的shell包含一些不同的內(nèi)置命令,通常不需要shell到磁盤中去搜索。通過help命令可以看到有哪些內(nèi)置命令:

          $?help

          通過type 命令可以查看命令類型:

          $?type?echo
          echo?is?a?shell?builtin

          如果是內(nèi)置命令,則會直接執(zhí)行,否則繼續(xù)查找。

          PATH中查找

          以ls為例,在shell輸入ls時,首先它會從PATH環(huán)境變量中查找,PATH內(nèi)容是什么呢,我們看看:

          $?echo?$PATH
          /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

          所以它會在這些路徑下去尋找ls程序,按照路徑找到的第一個ls程序就會被執(zhí)行。使用whereis也能確定ls的位置:

          $?whereis?ls
          ls:?/bin/ls?/usr/share/man/man1/ls.1.g

          既然它是在bin目錄下,那么我把ls從bin目錄下移走是不是就找不到了呢?是的。

          $?mv?/bin/ls?/temp/ls_bak??#測試完后記得改回來奧

          現(xiàn)在再來執(zhí)行l(wèi)s命令看看:

          $?ls?
          The?program?'ls'?is?currently?not?installed.?You?can?install?it?by?typing:
          apt?install?coreutils

          沒錯,它會提示你沒有安裝這個程序或者命令沒有找到。

          所以你現(xiàn)在明白為什么你第一次安裝jdk或者python的時候要設(shè)置環(huán)境變量了吧?不設(shè)置的話行不行?

          行。這個時候你就需要指定路徑了。怎么指定路徑?無非就是那么幾種,相對路徑,絕對路徑等等。
          比如:

          $?cd?/temp
          $?./ls_bak

          或者:

          $?/temp/ls_bak

          是不是發(fā)現(xiàn)和運行自己的普通程序方式?jīng)]什么差別呢?

          到這里,如果還沒有找到你要執(zhí)行的命令,那么就會報錯。

          確定解釋程序

          在找到程序之后呢,需要確定解釋程序。什么意思呢?
          shell通常可以執(zhí)行兩種程序,一種是二進制程序,一種是腳本程序。

          而一旦發(fā)現(xiàn)要執(zhí)行的程序文件是文本文件,且文本未指定解釋程序,那么就會默認當成shell腳本來執(zhí)行。例如,假設(shè)有test.txt內(nèi)容如下:

          echo?-e?"hello?world"

          賦予執(zhí)行權(quán)限并執(zhí)行:

          $?chmod?+x?test.txt
          $?./test.txt
          hello?world

          當然了,我們通常會在shell腳本程序的來頭帶上下面這句:

          #!/bin/bash

          這是告訴shell,你要用bash程序來解釋執(zhí)行test.txt。作為一位調(diào)皮的開發(fā)者,如果開頭改成下面這樣呢?

          #!/usr/bin/python

          再次執(zhí)行之后結(jié)果如下:

          $?./test.txt
          ??File?"./test.txt",?line?2
          ????echo?-e?"hello?world"
          ????????????????????????^
          SyntaxError:?invalid?syntax

          是的,它被當成python腳本來執(zhí)行了,自然就會報錯了。

          那么如果是二進制程序呢?就會使用execl族函數(shù)去創(chuàng)建一個新的進程來運行新的程序了。

          小結(jié)一下前面的內(nèi)容,就是說,如果是文本程序,且開頭沒有指定解釋程序,則按照shell腳本處理,如果指定了解釋程序,則使用解釋程序來解釋運行;對于二進制程序,則直接創(chuàng)建新的進程即可。

          來源:公眾號【編程珠璣】
          id:shouwangxiansheng

          運行

          前面我們也已經(jīng)看到了運行方式,設(shè)置環(huán)境變量或者使用相對路徑,絕對路徑即可。不過對于shell腳本,你還可以像下面這樣執(zhí)行:

          $?sh?test.txt
          $?.?test.txt??

          即便test.txt沒有執(zhí)行權(quán)限,也能夠正常執(zhí)行。

          什么?你說為什么txt也能執(zhí)行?注意,Linux下的文件后綴不過是為了方便識別文件類型罷了,以.txt結(jié)尾,并不代表一定是文本。當然在這里它確實是,而且還是ASCII text executable:

          $?file?test.txt
          test.txt:?Bourne-Again?shell?script,?ASCII?text?executable
          $?file?hello
          hello:?ELF?64-bit?LSB?executable,?x86-64,?version?1?(SYSV),?dynamically?linked,?interpreter?/lib64/l,?for?GNU/Linux?2.6.32,?BuildID[sha1]=8ae48f0f84912dec98511581c876aa042824efdb,?not?stripped

          擴展一下

          那么如果讓我們自己的程序也能夠像Linux內(nèi)置命令一樣輸入即可被識別呢?

          將程序放到PATH路徑下

          第一種方法就是將我們自己的程序放到PATH中的路徑中去,這樣在shell輸入hello時,也能找到,例如我們將其放在/bin目錄下:

          $?hello
          hello?world
          $?whereis?hello
          hello:?/bin/hello

          也就是說,如果你的程序安裝在了PATH指定的路徑,就需要配置PATH環(huán)境變量,在命令行輸入就可以直接找到了。

          設(shè)置PATH環(huán)境變量

          那么如果想在指定的目錄能夠直接運行呢?很簡單,那就是添加環(huán)境變量,例如將當前路徑加入到PATH中:

          $?PATH=$PATH:./???#這種方式只在當前shell有效,所有shell生效可修改/etc/profile文件
          $?hello
          hello?world

          設(shè)置別名

          例如:

          $?alias?hello="/temp/hello"
          $?hello
          hello?world

          以上三種方法都可以達到目的。

          執(zhí)行順序

          那么假設(shè)我寫了一個自己的printf程序,當執(zhí)行printf的時候,到底執(zhí)行的是哪一個呢?
          實際上它的查找順序可以可以通過type -a來查看:

          $?type?-a?printf
          printf?is?aliased?to?`printf?"hello\n"'
          printf?is?a?shell?builtin
          printf?is?/usr/bin/printf
          printf?is?./printf

          這里就可以很清楚地看到查找順序了。也就是說,如果你輸入printf,它執(zhí)行的是:

          $?printf
          hello

          而如果刪除別名:

          unalias?printf

          它執(zhí)行的將會是內(nèi)置命令printf。
          以此類推。

          總結(jié)

          說到這里,想必標題的問題以及下面的問題你都清楚了:

          • 安裝Python或者Jdk程序為什么要設(shè)置PATH環(huán)境變量?如果不設(shè)置,該如何運行?

          • 除了./方式運行自己的程序還有什么方式?

          • 如果讓自己的程序能夠像內(nèi)置命令一樣被識別?

          • 如何查看文件類型?

          • 執(zhí)行一條命令,如何確定是哪里的命令被執(zhí)行

          本文涉及命令:

          • mv 移動/重命名

          • file 查看文件信息

          • whereis 查看命令或者手冊位置

          • type 查看命令類別



          ? 推薦閱讀:

          ? ??專輯|Linux文章匯總
          ? ??專輯|程序人生
          ? ??專輯|C語言


          嵌入式Linux
          微信掃描二維碼,關(guān)注我的公眾號?
          瀏覽 47
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费一级特黄特色大片 | 国产精彩视频 | 理论片人人操人人摸 | 五月婷婷综合91 | 操逼香蕉 |