成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Linux:system 調用引發(fā)的 getcwd 異常

TesterHome / 1557人閱讀

摘要:背景幸福的生活總是相似的,天降的大鍋各有各不同。那現(xiàn)在其實一目了然了,調用了觸發(fā)初始化了,在初始化變量時候調用了,因為獲取父目錄失敗了,所以輸出了那段錯誤。

背景

幸福的生活總是相似的,天降的大鍋各有各不同。

我們有個功能是這樣的:有個以 root 運行的 python 程序,它需要以 test 用戶執(zhí)行 linux 命令,所以就通過 subprocess 庫 + sudo 來執(zhí)行,也就是下面的關系圖:

./test_b 就是這么一個很簡單的需求,本來是沒有什么太大的問題的,然而事實總是喜歡打我們臉。

就輸出下面的錯誤了:

雖然上面的錯誤不會影響程序的運行,但是處女座沒法忍,一定要干干凈凈,明明白白!

錯誤定位

憑借過硬的英語水平,我們明白這個報錯是因為訪問不到父目錄導致 getcwd 出錯了。

聰明的童鞋一想就覺得是不是和上面的刪除目錄有關系,這時候肯定得看看 test_b 是什么內容,說不定能解決我們的疑問:

#!/usr/bin/python
import time
import os

time.sleep(3)
os.system("sleep 1")

那么問題來了,test_b 明明就只想睡個覺,不想涉足江湖事,也沒有調用getcwd,為什么會輸出這個報錯咧!

在我們毫無頭緒時,可以去喝喝快樂肥宅水,說不定就能脈動回來。

因為我就是這樣看到找到線索了:shell-init。

憑借過硬的英語水平,我們可以看到這個錯誤應該在 shell 初始化時候報的,這樣很明顯啦,去搜 bash 代碼。

很快我們就找到這句錯誤定義的地方了:

[email protected] $ grep  "shell-init" -r *
variables.c:      temp_string = get_working_directory ("shell-init");

看到 get_working_directory 這個函數(shù)名這么正規(guī),感覺這事靠譜了,順著看看內容:

// builtins/common.c
char *
get_working_directory (for_whom)
     char *for_whom;
{
    ... (跳過)
    if (the_current_working_directory == 0)
    {
      fprintf (stderr, _("%s: error retrieving current directory: %s: %s
"),
           (for_whom && *for_whom) ? for_whom : get_name_for_error (),
           _(bash_getcwd_errstr), strerror (errno));
      return (char *)NULL;
    }
    ... (跳過)
}

雖然大部分是通過變量傳值進去,但是還是能看出就是咱們那句報錯的原型了,

其實上面的代碼實現(xiàn)并不是最關鍵的,關鍵的是,這些代碼文件是在 bash 里面的,為什么system 會和bash 扯上關系呢?難道 system 還需要擼一發(fā) shell 么,崩潰!我心目中的 system 不是這么隨便的!

System 源碼

帶著不甘心去搜它的實現(xiàn):

int system(const char * cmdstring)
{
    pid_t pid;
    int status;
    
    if(cmdstring == NULL){ 
         return (1);
    }
    
    if((pid = fork())<0){
         status = -1;
    }
    else if(pid = 0){

        execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);

        exit(127); //子進程正常執(zhí)行則不會執(zhí)行此語句

    }
    else{
        while(waitpid(pid, &status, 0) < 0){
            if(errno != EINTER){
                status = -1;
                break;
            }
        }
    }
    return status;
}

它的出廠設置就是這樣,原來是我一直沒去深入了解它。

那現(xiàn)在其實一目了然了,system調用了 /bin/sh, 觸發(fā)shell 初始化了, 在初始化變量時候調用了
get_working_directory,因為獲取父目錄失敗了,所以輸出了那段錯誤。

既然我們知道錯誤是 system 輸出的,那么我們換個方式就應該能規(guī)避咯?

于是乎,./test_b 代碼改成這樣就不報錯了:

#!/usr/bin/python
import time
import os

time.sleep(3)
# os.system("sleep")
os.execl("/bin/sleep", "sleep", "1")

那么這里又引出了一個問題了

system 和 execl 都能執(zhí)行系統(tǒng)命令,那兩者有什么區(qū)別呢?

答案在上面的 system 的源碼已經給出 80% 了,他們的區(qū)別就是:

system = fork + execl + waitpid

execl 只是系統(tǒng) exec 族函數(shù)的其中一個,說到 exec 族函數(shù),它們是將新的程序內容替換當前進程內容運行,具體大家可以去谷歌看看,這邊就不多說了~

我們對 system 的實現(xiàn)已經有一定熟悉了,在后面使用這個方法時候,不管是在資源使用還是問題排查,都應該多一些意識,眼不見不代表沒關系~

歡迎各位大神指點交流, QQ討論群: 258498217
轉載請注明來源: https://segmentfault.com/a/11...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/42856.html

相關文章

  • python中sys,os,time模塊使用(包括時間格式各種轉換)

    摘要:模塊實現(xiàn)從程序外部向程序傳遞參數(shù)。位置參數(shù)代表文件本身,運行方法參數(shù),參數(shù)。。是正常退出,其他為異常第次第五次退出模塊判斷現(xiàn)在正在實用的平臺,返回返回得到當前工作的目錄。指定所有目錄下所有的文件和目錄名。例檢驗指定的對象是否存在。 sys模塊 sys.argv: 實現(xiàn)從程序外部向程序傳遞參數(shù)。 位置參數(shù)argv[0]代表py文件本身,運行方法 python xx.py 參數(shù)1,參數(shù)2 ...

    mochixuan 評論0 收藏0
  • Android實際開發(fā)bug大總結

    摘要:換句話說,環(huán)境或應用程序沒有處于請求操作的適當狀態(tài)。項目中異常分析引發(fā)崩潰日志的流程分析解決辦法常見的出現(xiàn)場景狀態(tài)異常非法線程操作。導致的方法出來顯示消息位于該消息之后,遲遲沒有執(zhí)行。這時候,的超時檢測結束,刪除了服務中的記錄。 目錄介紹 1.1 java.lang.UnsatisfiedLinkError找不到so庫異常 1.2 java.lang.IllegalStateExce...

    peixn 評論0 收藏0
  • 崩潰bug日志總結2

    摘要:出現(xiàn)錯誤引發(fā)崩潰日志的流程分析這個錯誤是應用的方法總數(shù)限制造成的。 目錄介紹 1.1 java.lang.ClassNotFoundException類找不到異常 1.2 java.util.concurrent.TimeoutException連接超時崩潰 1.3 java.lang.NumberFormatException格式轉化錯誤 1.4 java.lang.Illegal...

    sutaking 評論0 收藏0

發(fā)表評論

0條評論

TesterHome

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<