談一談跑PHP計劃任務

來源:互聯網
上載者:User

標籤:inux   使用者登陸   put   導致   munmap   ifd   使用者   解決辦法   wro   

公司所用計劃任務均是大概這樣子的:

*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testOne >/dev/null 2>&1*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testTwo >/dev/null 2>&1

可以看到把輸出與標準錯誤進行重新導向到空裝置了,這樣做是有一定原因的。查閱了一些資料,在這裡描述一下:

1.ssh登陸伺服器
2.建立一個php檔案test.php,代碼如下:

<?phpsleep(50);echo "aaa\n";file_put_contents("/tmp/test.txt",time());?>

3.用以下命令執行test.php程式

$ php test.php &

查看 /tmp/test.txt 檔案的內容為1497613738

4.然後再次執行如下命令。命令執行後,馬上使用exit命令退出登陸

$ php test.php &

5 然後ssh登陸伺服器,發現/tmp/test.txt 檔案的內容依然是 1497613738。說明第二次執行test.php時,file_put_contents函數沒有執行,或者沒有執行成功。

6 使用strace進行追蹤:

正常情況下的追蹤:
strace -p 1475
結果:
Process 1475 attachedrestart_syscall(<... resuming interrupted call ...>) = 0write(1, "aaa\n", 4aaa)                    = 4lstat("/tmp/test.txt", 0x7ffe792ebe90)  = -1 ENOENT (No such file or directory)lstat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=65536, ...}) = 0open("/tmp/test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0lseek(3, 0, SEEK_CUR)                   = 0write(3, "1497614186", 10)              = 10close(3)                                = 0munmap(0x7f4840239000, 528384)          = 0close(2)                                = 0close(1)                                = 0munmap(0x7f4847510000, 4096)            = 0close(0)                                = 0munmap(0x7f4847511000, 4096)            = 0sched_getaffinity(1475, 128, {ffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) = 128sched_setaffinity(0, 128, {ffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) = 0munmap(0x7f48404c8000, 2119936)         = 0munmap(0x7f48406ce000, 2345056)         = 0munmap(0x7f4840b39000, 2162536)         = 0munmap(0x7f484090b000, 2282472)         = 0munmap(0x7f4840d49000, 323584)          = 0exit_group(0)                           = ?+++ exited with 0 +++[1]+  Done                    php test.php

退出後再登陸的追蹤:

strace -p 3881

restart_syscall(<... resuming interrupted call ...>) = 0write(1, "aaa\n", 4)                    = -1 EIO (Input/output error)munmap(0x7f6b7fc04000, 528384)          = 0close(2)                                = 0close(1)                                = 0munmap(0x7f6b86edb000, 4096)            = 0close(0)                                = 0munmap(0x7f6b86edc000, 4096)            = 0sched_getaffinity(3881, 128, {ffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) = 128sched_setaffinity(0, 128, {ffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) = 0munmap(0x7f6b7fe93000, 2119936)         = 0munmap(0x7f6b80099000, 2345056)         = 0munmap(0x7f6b80504000, 2162536)         = 0munmap(0x7f6b802d6000, 2282472)         = 0munmap(0x7f6b80714000, 323584)          = 0exit_group(0)                           = ?+++ exited with 0 +++

通過對比可以看到echo處出現了 輸入/輸出錯誤,最終沒有執行file_put_contents函數。

7 原因:

為什麼退出登陸後,再登陸,就會發生EIO錯誤呢?這個和linux的會話處理有關。
當使用者ssh登陸一個伺服器時,也就開始了一個會話。會話開始後,標準輸入(stdin)、標準輸出(stdout)、標準錯誤(stderr)會串連到一個對應的終端(pty)。
使用者登陸後,任何標準輸出都會在終端中有反應。標準輸出的檔案控制代碼是1。因此,php中的echo("aaa\n") 會導致執行系統調用write(1, "aaa\n", 4). 會在終端中寫aaa\n。
?當使用者退出登陸時,一個會話就結束了。會話結束時,修改所有開啟該終端的檔案控制代碼,改成不可讀也不可寫;
?使用者退出登陸後再執行write(1, "aaa\n", 4),會報EIO錯誤。因為終端控制代碼已經不可寫。EIO錯誤發生後,導致進程結束。

解決辦法
方法一:
?使用重新導向符號&把標準輸出重新導向到空洞。

$ php test.php > /dev/null 2 >&1 &   這裡的& 可以用也可以不用

方法二:
使用nohup。

$ nohup php test.php &

說明:

 如果你正在運行一個進程,而且你覺得在退出帳戶時該進程還不會結束,那麼可以使用nohup命令。

該命令可以在你退出帳戶/關閉終端之後繼續運行相應的進程。nohup就是不掛起的意思( n ohang up)。

而我們公司採用的是第一種方法,關於對/dev/null 2 >&1 & 的描述,看另外一篇文章http://www.cnblogs.com/zhenghongxin/p/7029173.html

談一談跑PHP計劃任務

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.