1. 程式人生 > >chmod u+s用法和setuid(),seteuid()

chmod u+s用法和setuid(),seteuid()

在使用 setuid() 函式時會遇到 3 個關於 ID 的概念:
real user ID -- 真實使用者 ID
effective user ID -- 有效使用者 ID
saved set-user-ID -- 儲存了的設定使用者 ID。

真實使用者 ID (real user ID) 就是通常所說的 UID,在 /etc/passwd 中能看到它的身影,如:

beyes:x:1000:1000:beyes,206,26563288,63230688:/home/beyes:/bin/bash
它用來標識系統中各個不同的使用者。普通使用者無法改變這個 ID 值。

有效使用者 ID (effective) 表明,在執行一個程式時,你是以哪種有效身份執行它的。一般而言,有效使用者ID 等於 真實使用者 ID。這兩個 ID 值可以用
geteuid()
getuid() 函式獲取。
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    printf ("The real user ID is: %d\n", getuid());
    printf ("The effective user ID is :%d\n", geteuid());
    return (0);
}
編譯程式後,檢視生成的可執行檔案許可權:
$ls -l getuid.exe
-rwxr-xr-x 1 beyes beyes 4775 Jun  9 15:38 getuid.exe
普通使用者執行
$ ./getuid.exe
The real user ID is: 1000
The effective user ID is :1000
root 使用者執行
# ./getuid.exe
The real user ID is: 0
The effective user ID is :0
這就是所說的一般情況:實際使用者ID == 有效使用者 ID

下面看不一致的情況
使用 chmod 改變該程式的有效許可權位(suid):
$ chmod u+s getuid.exe
$ ls -l getuid.exe
-rwsr-xr-x 1 beyes beyes 4775 Jun  9 15:38 getuid.exe

再使用普通使用者執行:
$ ./getuid.exe
The real user ID is: 1000
The effective user ID is :1000
切換到 root 使用者執行:
# ./getuid.exe
The real user ID is: 0
The effective user ID is :1000
從 root 執行輸出來看,有效使用者 ID 的值為 1000 。也就是說,root 執行這個程式時,是沒有 root 的許可權的,它只有 beyes 這個普通使用者(實際使用者 ID 為 1000)的許可權。關於設定有效許可權位可以參考:http://www.groad.net/bbs/read.php?tid-367.html

下面用一個例項來驗證 root 執行此程式時只有 beyes 這個普通使用者的許可權,按下面步驟來進行:

1. 現在 /root 目錄下建立一個普通的文字檔案 rootfile.txt :
# echo "hello world" > /root/rootfile.txt
# ls -l /root/rootfile.txt
-rw-r--r-- 1 root root 12 Jun  9 15:48 /root/rootfile.txt

2. 修改上面的程式程式碼為:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
 
int main(void)
{
    const char *file = "/root/rootfile.txt";
     
    printf ("The real user ID is: %d\n", getuid());
    printf ("The effective user ID is :%d\n", geteuid());
 
    if (!unlink (file)) 
        printf ("Ok, I am root, and I can delete the file which in /root directory.\n");
    else
        perror ("unlink error");
 
    return (0);
}
在上面的程式碼中所要做的事情很簡單,就是要嘗試刪除 /root/rootfile.txt 這個檔案。使用普通使用者來編譯該程式。

現在先使用普通使用者來執行該程式:
$ ./getuid.exe
The real user ID is: 1000
The effective user ID is :1000
unlink error: Permission denied
很自然,普通使用者沒有許可權刪除 /root 下的檔案。

下面使用 root 來執行該程式:
# ./getuid.exe
The real user ID is: 0
The effective user ID is :0
Ok, I am root, and I can delete the file which in /root directory.
也很正常,root 有許可權刪除它目錄下的檔案。

現在為這個程式新增有效許可權位,注意這裡是用普通使用者執行的 chmod 命令:
[email protected]:~$ chmod u+s getuid.exe
[email protected]:~$ ls -l getuid.exe
-rwsr-xr-x 1 beyes beyes 5211 Jun 10 10:45 getuid.exe
再次分別以 普通使用者 和 root 使用者執行上面的程式:

普通使用者
$ ./getuid.exe
The real user ID is: 1000
The effective user ID is :1000
unlink error: Permission denied
還是一樣,普通使用者並沒有許可權刪除 /root 下的檔案。

root 使用者
# ./getuid.exe
The real user ID is: 0
The effective user ID is :1000
unlink error: Permission denied
由輸出可見,root 使用者也沒法刪除該檔案!同時我們看到,此時的 有效使用者 ID 值為 1000,所以我們知道,這個程式所賦予操作檔案的許可權不但要檢查實際使用者ID,更重要的是要考慮 有效使用者ID ;如果 有效使用者 沒有許可權刪除,那麼換成 root 使用者它也相當於被降權了,當然這個降權僅限於在這個程式的空間中。

下面通過 setuid() 和 seteuid() 這兩個函式來考察一下 saved set-user-ID (儲存的設定使用者ID)這個概念。

在使用 setuid() 時會遇到如下情況:
1. 若程序有 root 許可權,則函式將實際使用者 ID、有效使用者 ID 設定為引數 uid  。見如下程式碼:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
  
void show_ids(void)
{
    printf ("real uid: %d\n", getuid());
    printf ("effective uid: %d\n", geteuid());
}
  
int main(int argc, char *argv[])
{
      
    int uid;
    show_ids();
    uid = atoi(argv[1]);
  
    if (setuid (uid) < 0) 
        perror ("setuid error");
        
    show_ids();
  
    return (0);
}
下面使用 root 使用者來執行上面的程式:
# ./setuid.exe 1001
real uid: 0
effective uid: 0
real uid: 1001
effective uid: 1001
由此可見,在 root 下,實際使用者 ID 和有效使用者 ID 均被設為 setuid() 的引數 uid 的值。

2. 若程序不具有 root 許可權,那麼普通使用者使用 setuid() 時引數 uid 只能是自己的,沒有許可權設定別的數值,否則返回失敗:
使用普通使用者來執行:
$ ./setuid.exe 1001
real uid: 1000
effective uid: 1000
setuid error: Operation not permitted
real uid: 1000
effective uid: 1000
由以上可以看出,只有超級使用者程序才能更改實際使用者 ID 。所以一個非特權使用者程序不能通過 setuid 或 seteuid 得到特權使用者許可權。

這裡考慮 su 這個程式,su 可以將普通使用者切換到 root 使用者。這是因為,su 被設定了 有效許可權位:
# ll /bin/su
-rwsr-xr-x 1 root root 29152 Feb 16 04:50 /bin/su
如上面所做實驗描述的一樣,普通使用者在執行 su 時,它也就擁有了 root 的許可權。

對於呼叫了 setuid() 函式的程式要格外小心,當程序的有效使用者 ID 即 euid 是 root 使用者時(設定了有效許可權位),如果呼叫了 setuid() ,那麼它會與它相關的所有 ID (real user ID, effective user ID,saved set-user-ID) 都變成它引數裡所設的 ID,這樣該程序就變成了普通使用者程序,也就再也恢復不了 root 許可權了。看下面程式碼:
#include <stdio.h>
#include <stdlib.h>
  
void show_ids (void)
{
        printf ("The real user ID is: %d\n", getuid());
        printf ("The effective user ID is :%d\n", geteuid());
}
  
int main(void)
{
        const char *file = "/root/rootfile3.txt";   
        setuid (0)
        show_ids();
        if (!unlink (file)) {
                printf ("Ok, I am root, and I can delete the file which in /root directory.\n");
                system ("echo hello world > /root/rootfile3.txt");
                printf ("Now, drop the root privileges.\n");
                if (setuid (1000) < 0) {
                        perror ("setuid");
                        exit (EXIT_FAILURE);
                }
                show_ids();
                if (unlink (file) < 0) {
                        printf ("Ok, we have no privilege to delete rootfile.txt.\n");
                }
                printf ("try to regain root power again...\n");
                if (seteuid (0)) {
                        perror ("seteuid");
                        show_ids();
                        exit (EXIT_FAILURE);
                }
        }
我們使用 root 編譯上面的程式,並執行 chmod u+s 給程式新增 suid 位,然後以普通使用者來執行它:
# ./getuid3 The real user ID is: 0The effective user ID is :0Ok, I am root, and I can delete the file which in /root directory.Now, drop the root privileges.The real user ID is: 1000The effective user ID is :1000Ok, we have no privilege to delete rootfile.txt.try to regain root power again...seteuid: Operation not permittedThe real user ID is: 1000The effective user ID is :1000
由輸出可見,在執行 setuid (1000) 函式時,我們還是具有 root 許可權的,所以該函式會設定成功。正是因為有了 root 許可權,所以 3 個 ID (真實使用者ID,已儲存使用者ID,有效使用者ID)都會被設定為 1000。所以在執行完 setuid(1000) 後,程序已經被降權為普通使用者,此時想再  seteuid (0) 提高許可權已經不可能。這裡需要提到一點,對於 show_ids() 函式裡,我們無法獲取 儲存的設定使用者ID(saved set-user-ID),這是因為沒有這種 API 。但是我們知道這個約定:當用戶是 root 時,使用 setuid() 來修改 uid,這 3 個 ID 是會被同時都修改的。但是有沒有辦法,先使程序降權後在某些時候再恢復 root 權力呢?辦法是使用 seteuid() 而不是 setuid() 。那 setuid() 和 seteuid() 有什麼不同麼?在 seteuid() 的 man 手冊裡提到:
seteuid() sets the effective user ID of the calling process.  Unprivileged user processes may only set the effective user ID to the real user ID, the effec‐tive user ID or the saved set-user-ID.
setedui() 用來設定呼叫程序的有效使用者 ID。普通使用者程序只能將 有效使用者ID 設定為 實際使用者ID,有效使用者ID,儲存的設定使用者ID。這裡比較重要的是,seteuid() 中的引數可以被設定為 儲存的設定使用者 ID 。儲存的設定使用者 ID 是這樣的一種概念:它是從 exec 複製有效使用者 ID 而得來的。具體的說,當我們從一個 shell 裡執行一個外部命令時(這裡就當做是執行上面的 getuid3 這個),如果該程式設定了使用者ID位(有效許可權位),那麼在 exec 根據檔案的使用者ID設定了程序的有效使用者 ID 後,就會將這個副本儲存起來。簡單的說,saved set-user-ID 儲存了 有效使用者ID 的值。比如對於 getuid3 這個程式,saved set-user-ID 儲存的值就是 0 。據此,我們修改上面的 getuid3 程式程式碼為:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
 
void show_ids (void)
{
        printf ("The real user ID is: %d\n", getuid());
        printf ("The effective user ID is :%d\n", geteuid());
}
 
int main(void)
{
        const char *file = "/root/rootfile3.txt";
 
        show_ids();
        if (!unlink (file)) {
                printf ("Ok, I am root, and I can delete the file which in /root directory.\n");
                system ("echo hello world > /root/rootfile3.txt");
                printf ("Now, drop the root privileges.\n");
                if (seteuid (1000) < 0) {
                        perror ("setuid");
                        exit (EXIT_FAILURE);
                }
                show_ids();
                if (unlink (file) < 0) {
                        printf ("Ok, we have no privilege to delete rootfile3.txt.\n");
                }
                printf ("try to regain root power again...\n");
                if (seteuid (0)) {
                        perror ("seteuid");
                        show_ids();
                        exit (EXIT_FAILURE);
                }
        }
                show_ids();
 
                printf ("try to delete rootfile3.txt again\n");
                if (!unlink(file)) {
                        printf ("Ok, regain root power successful!\n");
                        system ("echo hello world > /root/rootfile3.txt");
                        return (0);
                }
 
        return (0);
}
在上面的程式碼中,我們將原來的 setuid(1000) 替換為 seteuid(1000); 。並且在此後,再次嘗試刪除 /root/rootfile3.txt 這個檔案。下面在普通使用者下執行該程式:
[email protected]:~/C/syscall/getuid$ ./getuid3
The real user ID is: 1000
The effective user ID is :0
Ok, I am root, and I can delete the file which in /root directory.
Now, drop the root privileges.
The real user ID is: 1000
The effective user ID is :1000
Ok, we have no privilege to delete rootfile3.txt.
try to regain root power again...
The real user ID is: 1000
The effective user ID is :0
try to delete rootfile.txt again
Ok, regain root power successful!
此時我們看到整個過程:
先是普通使用者執行了具有 root 有效許可權位設定的程式,它成功的刪除了 /root 下面的一個文字檔案;然後使用 system() 系統呼叫恢復了該檔案,目的是方便下面繼續實驗。接著,它使用 seteuid() 函式時該程序降權為普通使用者許可權程序。此後,正是因為有了 saved set-user-ID 的儲存,所以當再次使用 seteuid() 恢復 程序的 root 許可權時可以恢復成功!

所以再次看到,setuid() 會改變 saved set-user-ID 的值而不能恢復許可權;而 seteuid() 不會改變 saved set-user-ID 這個值,所以它能夠恢復。

其他:

在使用setuid,seteuid,chmod u+s filename,chmod u-s filename等命令前,先弄清楚四個概念,分別是:檔案擁有者,real user ID, effective user ID, saved set-user-ID。

檔案擁有者:當你輸入 ls -l命令,可以檢視一個檔案的屬性,其中有該檔案的擁有者。

          -rw-rw-rw- 1 xy xy 1760 Jun  5 19:44 luoxuan.c

         上面這一欄就是ls -l命令的輸出,第三欄就是檔案擁有者,在這裡是xy。

real user ID:實際上程序的執行者,標誌系統中不同的使用者,普通使用者無法修改其值,某一個使用者的real user ID==他的uid,使用命令“id username"來檢視某使用者uid。

再來區分一下,real user ID與檔案所有者的概念,以下面程式碼作為範例。

複製程式碼
#include <stdio.h>
#include <stdlib.h>

int main(){
        int i;
        printf("The real user ID is: %d\n",getuid());
        printf("The effective  user ID is: %d\n",geteuid());
        i=setuid(100);
        if(0==i){
                printf(".......................\n");
                printf("The real user ID is: %d\n",getuid());
                printf("The effective  user ID is: %d\n",geteuid());
                printf(".......................\n");
        }
        else{
                perror("failed to setuid");
                printf("The real user ID is: %d\n",getuid());
                printf("The effective  user ID is: %d\n",geteuid());
                exit(1);
        }
        return 0;
}
複製程式碼

假設程式碼以普通使用者編譯,生成a.out可執行檔案,輸入“ls -l a.out",可以看見輸出為“-rwxr-xr-x 1 xy xy 7567 Jul  8 14:10 a.out”,a.out的所有者是xy。

          然後,執行./a.out命令,得到結果1:

                                  The real user ID is: 1003
                                  The effective  user ID is: 1003
                                  failed to setuid: Operation not permitted
                                  The real user ID is: 1003
                                  The effective  user ID is: 1003
          再執行sudo ./a.out命令,得到結果2:

                                  The real user ID is: 0
                                  The effective  user ID is: 0
                                  .......................
                                  The real user ID is: 100
                                  The effective  user ID is: 100

從輸出結果來看,先不理會effective user ID,當以普通使用者執行時,real user ID 為1003,無法setuid,也改變不了real user ID 的值;而使用了sudo 後,改變實際執行使用者為root許可權執行程序,real user ID的值也變為0,0是root的uid值,此時a.out這個檔案的所有者仍然是xy(1003),只不過使用了sudo 超級使用者許可權導致real user ID不一樣。

effective user ID: 主要用於檢驗該程序在執行時所獲得的訪問檔案許可權,當程序在訪問檔案時,檢查許可權,實際上是檢查effective user ID。有時候,real user ID==effective user ID,但很多時候又不一樣,具體情況後面再解釋。

仍以上面的程式碼作為例子,此時以普通使用者身份對a.out執行命令:chmod u+s a.out,再以"ls -l a.out"檢視a.out的檔案屬性,為"-rwsr-xr-x 1  xy xy 7567 Jul  8 14:10 a.out"。檔案屬性中多了一個s符號。
              再執行sudo ./a.out,得到結果3:

                                  The real user ID is: 0
                                  The effective  user ID is: 1003
                                  failed to setuid: Operation not permitted
                                  The real user ID is: 0
                                  The effective  user ID is: 1003

 對比結果2,儘管real user ID 是0(root uid),卻無法setuid,因為我們使用chmod u+s設定了effective user ID為1003(因為以普通使用者執行chmod u+s命令,所以effective user ID為1003),effective user id為1003時,即普通使用者,是無法使用setuid修改real user ID和effective user ID的值。所以此時,執行a.out程式的real user ID為0,而effective user ID為1003。

saved set-user ID: 當effective user ID修改時,儲存effective user ID的值。具體作用,我還不清楚,請看本文第一段的連結,那裡有詳細介紹。

從上面例子,觀察到一個事實,通過getuid()和geteuid()可以獲得real user ID和effective user ID的值,卻沒有函式獲得saved set-user-ID的值。

再來區分一下setuid和chmod u+s。

setuid : 修改real user ID和effective user ID。

chmod u+s filename: 將filename的effective user ID 改為當前登入使用者的許可權,比如上例結果3中,effective user ID為1003,即uid。即使使用sudo chmod u+s,結果也一樣,effective user ID仍為1003。

為了更加清晰地說明這個概念,我們再以上面的程式碼進行另一個試驗。假設以sudo cc test.c tuo.a編譯上述程式碼,生成tuo.a二進位制檔案,使用"ls -l tuo.a"檢視tuo.a的屬性,得到-rwxr-xr-x 1 root root 7567 Jul  8 14:53 tuo.a,uid是root。

      再以普通使用者執行./tuo.a,得到結果4:

      The real user ID is: 1003
      The effective  user ID is: 1003
      failed to setuid: Operation not permitted
      The real user ID is: 1003
      The effective  user ID is: 1003

      儘管這個檔案所有者(owner)是root,但實際執行使用者是普通使用者,所以real user ID和effective user ID都是1003,因此也無法執行setuid。

      再以sudo ./tuo.a執行,得到結果5:     

      The real user ID is: 0
      The effective  user ID is: 0
      .......................
      The real user ID is: 100
      The effective  user ID is: 100
      .......................
      這裡以root許可權執行。

      再來使用chmod u+s tuo.a,得到結果“chmod: changing permissions of `tuo.a': Operation not permitted”,因為chmod此時是普通使用者,無法修改root使用者的檔案(tuo.a),所以我們換成sudo chmod u+s tuo.a,再"ls -l tuo.a",可以看見“-rwsr-xr-x 1 root root 7567 Jul  8 14:53 tuo.a",注意紅色的s字幕,這就是chmod u+s的效力。現在再以普通使用者來執行一下tuo.a二進位制檔案,得到結果6:

      The real user ID is: 1003
      The effective  user ID is: 0
      .......................
      The real user ID is: 100
      The effective  user ID is: 100
       .......................
      此時,real user ID為1003, effective user ID為0,即使是普通使用者執行,還是可以setuid,因為effective user ID被chmod u+s 賦予了0(root許可權)。

這一類典型的檔案有/usr/bin/passwd,使用"ls -l /usr/bin/passwd"檔案檢視到“-rwsr-xr-x 1 root root 35696 Feb  8  2011 /usr/bin/passwd”,正是這個s標誌(也就是effective user ID)可以讓普通使用者以root許可權做一些事情,如登陸時密碼匹配。

如果不希望該檔案繼續擁有u+s許可權,可使用chmod u-s filename消除影響。

最後再來說一說sticky bit粘滯位。

sticky bit: 檔案寫許可權的一種擴充套件,當檔案被設定了sticky bit位,同一組的其他使用者他可以為該檔案新增內容,但不能刪除該檔案。使用命令chmod o+t filename,或者chmod 八進位制方式設定sticky bit位。設定好之後,用ls -l filename,可以看見一個標記“t"。請注意一個地方,即使添加了stickybit,檔案所有者也是可以隨意刪改這個檔案的。


相關連結:

http://www.makelinux.net/alp/083

http://en.wikipedia.org/wiki/User_identifier#Effective_user_ID


相關推薦

chmod u+s用法setuid()seteuid()

在使用 setuid() 函式時會遇到 3 個關於 ID 的概念: real user ID -- 真實使用者 ID effective user ID -- 有效使用者 ID saved set-user-ID -- 儲存了的設定使用者 ID。 真實使用者 ID (rea

chmod g+schmod o+t 、chmod u+s詳細說明

Set uid, gid,sticky bit的三個許可權的詳細說明 一個檔案都有一個所有者, 表示該檔案是誰建立的. 同時, 該檔案還有一個組編號, 表示該檔案所屬的組, 一般為檔案所有者所屬的組

Linux命令 chmod 例:chmod u+s

chmod u+s  就是給某個程式的所有者suid許可權,可以像root使用者那樣啟動。比如安裝nginx時, 一般會建立一個非root使用者,來啟動nginx。由於非root使用者不能佔用80埠所以使普通使用者以root身份啟動nginx。cd /ucenter/soft

Linux文件目錄權限:chmod、更改所有者所屬組:chownumask命令隱藏權限:lsattr/chattr

chmod chown umask 文件和目錄權限chmod: 我們使用ls -l可以看到文件的詳細信息,也知道第一列的第一個符號(字母)表示文件的類型,在表示文件的類型符號的後面的九個符號則表示的是文件的權限,這些權限和文件的所有者和所屬組都有關系:文件權限有三個屬性:是否可讀用r表示、是否可寫

forforeachiterator的用法區別

mar 有序 iter 這就是 內部類 易懂 叠代 object clas 不同點: 1.形式差別 for的形式是 for(int i=0;i<arr.size();i++){...} foreach的形式是 for(int i:arr){...} iterator的

淺談JS中的!=、== 、!==、===的用法區別 JS中Null與Undefined的區別 讀取XML文件 獲取路徑的方式 C#中CookieSessionApplication的用法與區別? c#反射 抽象工廠

main 收集 data- 時間設置 oba ase pdo 簡單工廠模式 1.0 var num = 1; var str = ‘1‘; var test = 1; test == num //true 相同類型 相同值 te

awk的基本概念基礎用法高級用法

awk 基本概念 基礎用法 高級用法 awk:文本處理三劍客:grep系,sed,awkgrep系:grep,egrep,fgrep,基於PATTERN進行文本過濾;sed:流編輯器,逐行編輯器;模式空間,保持空間;awk:報告生成器;格式化文檔輸出; awk是下面三個人的姓氏縮寫:

fgetsfputsfreadfwritefscanffprintf用法小結

fwrite fgets eof IT 意義 遇到 其中 文件 之前 一、fgets(str,n,fp); fgets(str,n,fp);就是從fp指向的文件中讀取n-1個字符送入字符數組str中。 說明:1、在讀出n-1個字符之前,如果遇到了換行符或者EOF,則讀出結束

shell腳本介紹shell腳本結構執行date命令用法shell腳本中的變量

shellShell腳本介紹 shell是一種腳本語言 blog.lishiming.net(阿銘的博客,可以去裏面找shell習題)可以使用邏輯判斷、循環等語法可以自定義函數,減少重復代碼shell是系統命令的集合shell腳本可以實現自動化運維,能大大增加我們的運維效率 Shell腳本結構和執行 開頭需

oracle 中的havingwhereminusunionnot exists的用法

最近在寫sql的時候用到了上面這幾個,就整理下 union all/union 這個函式可以將倆結果集合並在一起 例:當你用到in的時候,而in只能跟1000的欄位,這個時候就可以用 where 後面的條件不允許使用聚合函式,having可以。where 是對全表進行條件篩選,返回一個結

靜態方法類方法屬性setter用法delete用法屬性方法的應用場景

一、靜態方法  1.1、定義    在類中的方法前面通過@staticmethod裝飾器即可把其裝飾的方法變為一個靜態方法 1 2 3 4 5 6 7 8 9 10 class Person(object): &

C#裡式轉換法則isas的用法

裡式轉換法則:父類物件可以接收子類的實體,(和java中的多型是一樣的)                             父類中的方法用virtua

關於croncrondcrontab以及bash指令碼的寫法等知識 cron的語法用法

關於cron和crond,crontab以及bash指令碼的寫法等知識 cron的語法用法 原文:http://hlee.javaeye.com/blog/379801 當你的cronjob死活不執行時或者你在日誌裡看到 錯誤資訊" (*system*) BAD FI

python %r %s %d 用法區別

%可以理解為就是一個佔位符。python中用%代表格式符,表示格式化操作,常用的操作有%s,%d,%r等.%r用rper()方法處理物件%s用str()方法處理物件%d十進位制整數表示 #!/usr/local/python/bin/python # -*-coding=utf8 -*- x = "wei

breakcontinueC語言breakcontinue的用法區別

break 語句很重要,用得非常多,初學者一定要掌握。continue 語句雖然沒有 break 語句用得多,但也經常用到,而且不可或缺,需要用到 continue 的時候其他語句是無法替代的。 前面已經介紹過 break 語句,它不僅可以跳出“迴圈體”,還可以跳出 switch。但事實上,br

兩個字串st判斷t是否為s的重新排列後組成的

原始碼在linux裡面編譯測試通過,判斷t字串是否是s字元中的字元重新排序組合的。 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time

字串陣列擷取操作。 substringsubstr以及slicesplicecharAt()的用法

slice可運算元組和字串,但substring和substr只能操作字串,splice只能運算元組。 1.substr() substr() 方法可在字串中抽取從 start 下標開始的指定數目的字元。 語法 stringObject.substr(st

微信小程式全域性樣式(總的樣式)區域性樣式(頁面樣式)的用法區別。

首先,全域性樣式寫在app.wxss裡面, 當然,頁面樣式當然寫在各個頁面的樣式裡, 第二 ,呼叫全域性樣式需要在你寫的類後面或前面加上你全域性樣式定義的類,(樣式的類越排後面,優先順序越高!) 比如: 這是我定義的全域性樣式 然後我要在區域性樣式裡呼叫

C語言中scanf()sscanf(),fscanf()的用法區別

scanf(),sscanf(),fscanf()區別: 第一個是從控制檯(鍵盤)輸入; 第二個是從字串輸入; 第三個是從檔案輸入; scanf scanf()函式根據由format(格式)指定的格式從stdin(標準輸入)讀取,並儲存資料到其它引數.   int main

C語言中printf()sprintf()scanf()sscanf()的用法區別

printf 語法:    #include <stdio.h>   int printf( const char *format, ... ); printf()函式根據format(格式)給出的格式列印輸出到STDOUT(標準輸出)和其它引數中。返