2013-04-02 39 views
2

在Linux中使用二進制環境變量時,我發現一些奇怪的行爲,看起來有些單字節不好。我仔細檢查了它,看起來某些字節在給setenv()時總會被錯誤地「轉換」。看看這個:二進制環境變量和setenv()

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) 
{ 
    char array[256]; 

    int i; 
    for(i = 1; i < 256; i++) { 
     array[i] = i; 
    } 

    setenv("badenv", array, 1); 

    system("/bin/sh"); 

    return 0; 
} 

我執行這個程序,然後當我做echo $ badenv> test; hexdump都可以測試,我看到:

0000000 0101 0302 0504 0706 2008 0c0b 0e0d 100f 
0000010 1211 1413 1615 1817 1a19 1c1b 1e1d 201f 
0000020 2221 2423 2625 2827 2a29 2c2b 2e2d 302f 
0000030 3231 3433 3635 3837 3a39 3c3b 3e3d 403f 

看來,0x9轉換爲0x20,這是0xA轉化爲0XB,等等。

我濫用setenv(),或者甚至濫用環境變量?我查看了manpage並搜索了一些,看看環境變量是否應該能夠處理二進制值,但我不確定。

這種行爲的原因是什麼,有沒有辦法繞過它,同時仍然使用環境變量?

+0

對於什麼可以進入env變量似乎有一些沉默的限制。 'export a ='echo -e「\ t」'會產生同樣的效果,用tab替換空格。 – elmo

+0

由於'setenv'需要一個以0結尾的字符串(a.k.a. C-style字符串)作爲變量值,因此該值顯然不能是任意的二進制數據,因爲它不能很好地處理0字節。不過,我不知道爲什麼它會將「0x9」這樣的控制字符轉換爲空格。最可能的是一些安全措施。 – shakurov

回答

3

根據$IFS的值將環境變量拆分爲「單詞」,並將「單詞」與單個分隔符連接 - 在本例中爲普通空格。因此,在解釋array的內容時,序列"\x09\x0a""\t\n",會摺疊到一個空格('\x20')。

IFS - 即膨脹後和線與讀內建命令分成字用於字拆分內部字段分隔符。默認值是''space tab newline''。

您可以通過(暫時)更改$IFS來避免更換。

但是請注意,這

  • array[0]具有不確定的值在你的程序
  • array沒有0終結

。你應該解決這個問題。

+0

謝謝,我應該如何設置$ IFS以獲得此行爲?目前$ IFS沒有設置,我試着只聲明它沒有內容。 – csstudent2233

+0

你可以設置IFS =「」,然後一個(非空)空間序列被摺疊到一個空間,但由於只有一個空間,所以它不會被改變。但我很確定'IFS'已設置,'echo -n「$ IFS」| xxd'應該告訴你什麼(可能是空格,製表符,換行符,所以xxd會報告'2009 0a')。 –

+0

是的,你是對的。再次感謝,這似乎也使它在我原來的玩具程序中工作。我在這裏粘貼的程序只是用來展示一般「問題」的東西。 – csstudent2233