人為什麼都不肯死–賈平凹

文|賈平凹

人總是要死的。大人物的死天翻地覆,小人物說死,一閉眼兒,燈滅了,就死了。我常常想,真有意思,我能記得我生於何年何月何日,但我將死於什麼時候卻不知道。一覺睡起來,感覺睡著的那陣就是死了吧,睡夢是不是另一個世界的形態呢?我的一個畫家朋友,一個月里總要約我見一次,每次都要交我一份遺書,說他死後,眼睛得獻給某某醫院,心肺得獻給某某醫院。

過些日子,他又約我去,遺書又改了,說某某醫院管理混亂,決定把眼睛獻給另一個某某醫院的。對於死和將死的人見得多了,我倒有個偏見,如果說現在就業十分艱難,看一個孩子待父母孝順不孝順就看他能不能考上大學,那麼,評價一個人的歷史功過就得依此人死後是否還造福於民。秦始皇死了那麼多年,現在發掘了個兵馬俑坑,使中國贏得了那麼大的威名,又賺了那麼多旅遊參觀的錢,這秦始皇就是個好的。

人怕毛毛蟲,據說人是從小爬蟲衍變的,人也怕人,人也怕自己,怕自己死。在平日,壽比南山的話我們說得很多,萬壽無疆也喊過,是極少以死來恭維的話,死只能是對敵人最痛恨的詛咒,是法典中的極刑。

依我的經驗,三十歲以前,從來是不思考到死的,人到了中年,下一輩的人拔節似的往上長,老一茬的人接二連三地死去,死的概念動不動冒在心頭,幾個熟人湊一堆了,瞧,誰怎麼沒有來,死了,就說半天關於死的話題。凡能說到死的人,其實離死還遙遠,真正到了死神立於門邊,卻從不說死的。

Continue reading

狗的圖靈測試

給狗開發一款虛擬現實設備,連上虛擬世界的狗有真狗有假狗。人可以去那個世界扮狗。兩種玩法,一種降低智商,過一種正常的狗生,虛擬世界的狗基本都是真狗,遊戲結束可以瀏覽這一生。另一種是智商不變,但基本都是機器狗,有劇情模式和漫遊模式。@西部狗世界

額,忽然發現標題黨了,所以貼和圖靈測試的維基鏈接吧。

服務器連接pptp

需要從某網站頻繁獲取數據,但目標網站對IP限制嚴格,於是想到用vpn。市面上(淘寶)有種每次連接都會自動切換IP的PPTP VPN,很符合需求,下面就是怎麼用了,環境是CentOS6。

#安裝pptp
yum install pptp pptp-setup
#配置pptp
pptpsetup --create v --server vpn.server.address --username USERNAME --password PASSWORD
#淘寶的這種pptp vpn一般是不用加密設置的,萬一需要,可以在配置命令最後加--encrypt參數
#為了方便後續使用,我們複製兩個命令
cp /usr/share/doc/ppp-2.4.5/scripts/pon /usr/sbin/
cp /usr/share/doc/ppp-2.4.5/scripts/poff /usr/sbin/
chmod +x /usr/sbin/pon
chmod +x /usr/sbin/poff
#啟動pptp
pon v
#如果啟動成功路由表中應該會出現一個ppp0的設備
route -n
#如果沒出現可以查看那裡出了問題
tail -n 10 /var/log/messages | grep ppp
#這是如果把網關設置到ppp0所有流量就都走vpn了\
#但是啊,你將失去ssh連接,很恐怖吧\
#這時最好有服務器的網頁端供你連到內網進行操作\
#當然,重啟服務器也能恢復連接
#下面設置路由表
/sbin/route del -net default
/sbin/route add -net default dev ppp0
#此時所有流量就pptp了,通過下面命令查看
curl http://myip.dnsdynamic.org/
#執行需要pptp的ip完成的任務
#關閉vpn
poff
#理論上此時應該恢復之前的路由表
#但我偷了個懶,重啟了一下網絡
/etc/init.d/network restart
#從pon到重啟網絡,就完成了一個工作循環。

使用php腳本完成pptp的切換,其實就是php調用bash,兩點:運行用戶為root;命令最好寫相對路徑。

#!/usr/bin/php
<?php
class HttpClient{
    private $ch;

    function __construct($cookie_jar){
        $this->ch = curl_init();
        curl_setopt($this->ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0');
        curl_setopt($this->ch, CURLOPT_TIMEOUT, 40);
        curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($this->ch, CURLOPT_AUTOREFERER, true);
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($this->ch, CURLOPT_COOKIEJAR, $cookie_jar);
        curl_setopt($this->ch, CURLOPT_COOKIEFILE, $cookie_jar);
    }

    function __destruct(){
        curl_close($this->ch);
    }

    final public function setReferer($ref=''){
        if($ref != ''){
            curl_setopt($this->ch, CURLOPT_REFERER, $ref);
        }
    }

    final public function Get($url, $header=false, $nobody=false){
        curl_setopt($this->ch, CURLOPT_POST, false);
        curl_setopt($this->ch, CURLOPT_URL, $url);
        curl_setopt($this->ch, CURLOPT_HEADER, $header);
        curl_setopt($this->ch, CURLOPT_NOBODY, $nobody);
        return curl_exec($this->ch);
    }

    final public function Post($url, $data=array(), $header=false, $nobody=false){
        curl_setopt($this->ch, CURLOPT_URL, $url);
        curl_setopt($this->ch, CURLOPT_HEADER, $header);
        curl_setopt($this->ch, CURLOPT_NOBODY, $nobody);
        curl_setopt($this->ch, CURLOPT_POST, true);
        curl_setopt($this->ch, CURLOPT_POSTFIELDS, http_build_query($data));
        return curl_exec($this->ch);
    }
}

function getNewIP(){
    $logIPFile="/home/logIP.txt";
    $res=array();
    exec("/usr/sbin/pon v", $res);
    sleep(3);
    exec("/sbin/route del -net default", $res);
    sleep(2);
    exec("/sbin/route", $res);
    sleep(6);
    exec("/sbin/route add -net default dev ppp0", $res);
//	var_dump($res);
    sleep(1);
//    需要一個cookie文件,創建一個空文件即可
    $http = new HttpClient('/home/dump.txt');
    $ip = $http->Get("http://myip.dnsdynamic.org/");
    sleep(1);
    file_put_contents($logIPFile, date("Y-m-d H:i:s", time())."_".$ip.PHP_EOL , FILE_APPEND | LOCK_EX);

    $ips=array();
    exec("tail -n 2 '$logIPFile'", $ips);
    $isNewIP=0;
    foreach( $res as $oldIP ){
        if(strpos($oldIP, $ip) != false){
           $isNewIP=$isNewIP+1;
       }
    }

    return $isNewIP; 
}

function restoreIP(){
    exec("/usr/sbin/poff",$res);
//	var_dump($res);
    sleep(2);
    exec("/etc/init.d/network restart");
}

//如果IP沒有重複兩次以上就執行任務
if( getNewIP($logIPFile) <2 ){
//    doYourOwnStaff();
} 
restoreIP();
exit();
?>

crontab的設置,這裡不用crontab -e,而是直接編輯/etc/crontab:

nano /etc/crontab
#指定運行命令的用戶為root
03 * * * * root /path/to/the/script

這樣就完工了,感謝CentOS 6下配置PPTP VPN客户端在 Linux 命令列進行 PPTP VPN 連線。在完全不了解linux路由表和iptables的情況下,我也只能做到如此了。其實理想狀態是只轉發http和https到pptp,有空再研究吧,新年快樂!


由於政策原因,動態pptp沒那麼好買了。於是年後換了一批靜態pptp,做法就是新建多個pptp配置,然後隨機取。

$vpns = array("v47", "v11", "v18", "v12");
$rand_keys = array_rand($vpns, 2);
$vpn = $vpns[$rand_keys[0]] ;

在設置過程中,遇到了unknown authentication type 26; Naking錯誤,解決辦去掉/etc/ppp/options.pptp文件中的require-mppe-128的注釋,並在修改配置文件為如下:

# written by pptpsetup
pty "pptp SERVER --nolaunchpppd"
lock
noauth
refuse-pap
refuse-eap
refuse-chap
refuse-mschap

nobsdcomp
nodeflate
require-mppe-128
name MYUSERNAME
remotename CONFNAME
ipparam CONFNAME

另一種可能的錯誤是連接的時候出現LCP: timeout sending Config-Requests,我是通過chkconfig iptables off關閉iptables解決的,反正我在內網。

上文中的/etc/init.d/network restart有時並不能恢復本機網絡,此時我們可以替換腳本中的這一句為

#網關改回原來的網關
subprocess.call('/sbin/route add default gw 172.16.2.1 netmask 0.0.0.0 dev eth0', shell=True)

Linux硬盤滿

如果重啟後無法進入桌面環境,很可能是硬盤滿了,此時按Ctrl+Alt+F2進入命令行模式。

#查看磁盤空間剩餘情況
df -hl
#如果確實是磁盤可用空間不足
#則查看是那個文件夾里有大文件,一般都是/tmp
cd /tmp
#以文件夾大小排序,顯示最大的15個
du -hsx * | sort -rh | head -15

釋放出200M空間就差不多可以進桌面環境了。

在頻繁使用selenium調用火狐的時候,/tmp中會出現打量類似tmpzujczqpd的文件夾,可以使用下面代碼進行刪除。

import glob,shutil
def rmFirefoxTmpFile():
    usage = shutil.disk_usage('/tmp')
    #如果磁盤可用空間小於1G則執行刪除
    if usage.free<1024*1024*1024*1:
        #火狐產生的文件夾大概長這樣
        files = glob.glob('/tmp/tmp????????')
    
        for f in files:
            #刪除最後修改時間10個小時以前的文件夾
            if time.time() - os.path.getmtime(f)>10*60*60 :
                shutil.rmtree(f,True)
            

ssh connecting

記錄下ssh連接服務器的幾種方式:

linux to linux

直接打開終端,以帳號密碼方式登錄,如下:

ssh -l root -p 2016 123.159.181.162

如果厭倦了每次都要輸密碼,可以通過證書方式登錄,還能增加安全性。設置方法可以參考SSH Passwordless Login Using SSH Keygen in 5 Easy Steps,寫的很詳細。

android to linux

ConnectBot是一款簡單、強大、開放原始碼的SSH用戶端。增強鍵盤中方向鍵和Ctrl、Tab等鍵用起來很方便。而且它還能連local,就當作一個本地的Terminal了。

另一個選擇是JuiceSSH。其實呢從個方面(更強大的鍵盤和更便利的剪切板操作)我都覺得JuiceSSH比ConnectBot厲害,但是我還是要在一開始推薦一下開源軟件。

windows to linux

其實比putty厲害的軟件也有很多,但我只用過putty。

ios to linux

能用錢解決的問題都不是問題😉

Spy Monitor

Spy Monitor是個很有用的安卓應用,可以查看當前手機的網絡連接,並且不需要root權限。地圖模式下,顯示與當前手機有連接的遠程服務器所在地,可以看到微信有時在深圳,有時在上海,OperaMini的服務器確實是在中國,但OperaMoile則在冰島等等,挺有意思的。右邊列表模式能查看當前的活動鏈接以及鏈接的詳細,咦,我已經把"冰箱"用XPrivacy禁用了網絡,怎麼還有鏈接,而且還是連到ASHBURN, US,看來要去檢查下。

centos下可以用nethogs查看當前網絡鏈接。

windows下可以用NetWorx中的端口狀態查看當前網絡鏈接。

日期時間選擇器

使用bootstrap-datetimepicker來做出日期時間選擇器

<!DOCTYPE html>
<htmllang="zh-CN">
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript" src="./bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../js/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="../js/bootstrap-datetimepicker.js" charset="UTF-8"></script>
<script type="text/javascript" src="../js/locales/bootstrap-datetimepicker.zh-CN.js" charset="UTF-8"></script>
<script type="text/javascript" src="./Chart.bundle.min.js"></script>
<link href="./bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="../css/bootstrap-datetimepicker.min.css" rel="stylesheet" media="screen">

</head>
<body>
<br/>
<div class="container">
  <div>
    <form action="" class="form-inline"  role="form">
		  <div class="col-sm-12 col-md-2">
            <select name='appleIDOption' id='appleIDOption' class="form-control" >
            <!-- <option value="volvo">Volvo</option>  -->
            </select>     
        </div>   

        <div class="form-group col-sm-12 col-md-9">
            <label for="dtp_input1" class="col-md-2 control-label">开始时间</label>
            <div id="startTime" class="input-group date form_datetime col-md-4" data-date="" data-date-format="yyyy-mm-dd hh:ii" data-link-field="dtp_input1">
                <input class="form-control" size="16" type="text" value="" readonly>
                <span class="input-group-addon"><span class="glyphicon glyphicon-remove"></span></span>
				<span class="input-group-addon"><span class="glyphicon glyphicon-th"></span></span>
            </div>
			<input type="hidden" id="dtp_input1" data-date-format="yyyy-mm-ddThh:ii:ss" value="" />


            <label for="dtp_input2" class="col-md-2 control-label">结束时间</label>
            <div id="endTime" class="input-group date form_datetime col-md-4" data-date="" data-date-format="yyyy-mm-dd hh:ii" data-link-field="dtp_input2">
                <input class="form-control" size="16" type="text" value="" readonly>
                <span class="input-group-addon"><span class="glyphicon glyphicon-remove"></span></span>
				<span class="input-group-addon"><span class="glyphicon glyphicon-th"></span></span>
            </div>
			<input type="hidden" id="dtp_input2" data-date-format="yyyy-mm-ddThh:ii:ss" value="" /><br/>
        </div>		
    </form>	
		  <div class="col-sm-12 col-md-1">
          <button class="btn btn-default" id="query">查询</button>
        </div>
  </div>
</div>

<div id="charts" class="container" style="max-width:1600px;max-height:400px;"></div>

</body>
<script type="text/javascript">
    $('.form_datetime').datetimepicker({
        language:  'zh-CN',
        weekStart: 1,
        todayBtn:  1,
        autoclose: 1,
        todayHighlight: 1,
        startView: 2,
        forceParse: 0
    });

//沒有找到bootstrap-datetimepicker中轉出時間戳的格式,只好自己轉
//datastring後面不加+08:00的話Chrome會用+00:00,導致時間戳有誤
    $('#startTime').datetimepicker().on('hide', function(ev){
        $('#dtp_input1').val(Date.parse($('#dtp_input1').val().replace(' ',"T") + "+08:00"));
    });
    $('#endTime').datetimepicker().on('hide', function(ev){
        $('#dtp_input2').val(Date.parse($('#dtp_input2').val().replace(' ',"T") + "+08:00"));
    });

  $("#query").click(function(){
	    $( "#charts" ).empty();
	    var appleIDSelected = $('#appleIDOption').val();
//	    只取十位就好了
	    var startTime = $('#dtp_input1').val().substr(0,10);
	    var endTime = $('#dtp_input2').val().substr(0,10);
	    var postData = { appleID: appleIDSelected,startTime: startTime,endTime: endTime };
	    var jsonData = $.ajax({
		    url: 'keywordData.php',
		    method: 'POST',
		    data: postData,
		  }).done(function (results) {
//			  prepareChart(results);
		    });
	  });
</script>
</html>