FPs

Articles with the shell tag

echo 输出导致SCP 失效的问题

搭建了一个跳板机,强制使用密钥对登陆机器,同时需要用户在本地开启ForwardAgent,跳板机上创建SSH_AUTH_SOCK,透传私钥。然而常常有用户在本地没有正确配置,导致上了跳板机之后,再SSH 就会失败,于是我在跳板机的.bashrc 上写了一段检测脚本,如果变量$SSH_AUTH_SOCK 不存在,就引导用户去看Wiki,不要烦我啦!

用了一段时间,有用户发现scp 文件到跳板机时会失败,Google 一下:SCP doesn't work when echo in .bashrc?,怎么判断当前会话是scp?:Can I tell if I'm in an scp session in my .bashrc?

改下脚本:

if [ -n "$PS1" ] && [ -z $SSH_AUTH_SOCK ];then
   echo ""
   echo "创建SSH_AUTH_SOCK 失败!"
   echo "1.请在本机执行 ssh-add 添加私钥至 ssh-agent"
   echo "2.请在~/.ssh/config 配置:ForwardAgent yes"
   echo "详细帮助:wiki..."
   echo ""
fi

搞定!


一個改良的Ping

Ping 是一個非常常用的命令,有2種情況會使用它:
一是會從瀏覽器的地址欄或者其他人發給我的網址,複製,然後進行ping,帶着協議以及一堆uri和args,
例如: https://accounts.google.com/AddSession?hl=en...
二從Linux 系統的網絡地址複製過來IP,進行Ping,帶着掩碼位數,
例如:192.168.1.1/32

以上2種情況,如果直接複製內容到終端,然後ping,會提示:

ping: cannot resolve ....: Unknown host

很惱人,寫一個簡單的腳本:

#!/usr/bin/env bash
#author: fangpeishi@gmail.com
#issues:
#  - http(s)://xxx.xx/xxx/xx?xxx
#  - 192.168.1.1/32

new_args=`echo $@ |sed  's/http.*\:\/\///' |sed 's/\/[^ ]*//'`
#echo ${new_args}
ping ${new_args}

把這個腳本命名爲pin, 放到 /bin 之類的目錄下面即可(本來想做成alias,沒成功),最終效果如下:
pin


記一個退出終端進程不退出的問題

某一天開發同學問了一個問題,他們在線上跑一個job,沒用screen,nohup,把iTerm 窗口關了,job 沒掛。再登錄進去看,PPID 變成1,即進程被init 進程接管。
在對應機器上執行shopt, 發現:

...
gnu_errfmt      off
histappend      off
histreedit      off
histverify      off
hostcomplete    on
huponexit       off
interactive_comments    on
lastpipe        off
lithist         off
login_shell     on
mailwarn        off
...

注意CentOS 7 默認將huponexit 設爲off 了,这样在用户将Shell 退出结束会话时,系统不会發送 SIGHUP 給所有進程,這效果其實類似使用了nohup,nohup 的作用就是忽略HUP 信號。

huponexit
  If set, bash will send SIGHUP to all jobs when an interactive login shell exits.

Google Shell 編程風格指南

背景

使用哪種Shell

Bash 是唯一被允許用於編寫可執行文件的Shell 腳本語言(譯注:存在多種Shell語言,可參考Wikipedia:Unix_Shell
可執行文件必須以#!/bin/bash 開始(譯注:Wikipedia:Shebang),並且使用最小數量的執行選項(譯註:Find out what your UNIX shell’s flags are & then change them, The Set Builtin)。
使用set設置shell 執行選項,以便用bash <腳本名> 的方式調用腳本時候不會破壞執行選項的功能。
限制所有的可執行shell 腳本統一使用bash 使得我們在機器上能統一安裝一種shell 。 唯一的例外,你正在編寫的項目強制你使用其他shell 語言。例如Solaris SVR4 軟件包要求包內的任何腳本用純Bourne shell 編寫(譯註:即sh,參考Wikipedia:Bourne_shell)。

什麼時候使用Shell

Shell 應該只用於編寫小工具或者簡單的包裝腳本(譯註:wrapper scripts,Shell Wrappers)。
儘管shell 腳本不是一種開發語言,但在Google 內部它被用於編寫各種各樣的工具性腳本。在廣泛的開發部署中,遵循這份編程風格指南是一種共識,而不是一個建議。

一些準則:

  • 如果你主要是調用其他工具和做相對少量的數據處理,使用shell 來完成任務是合適的選擇。
  • 如果你在意性能,請使用其他工具來代替shell。
  • 任何情況下,如果你發現需要使用數組(譯註:Bash:Array variables),並且不是使用${PIPESTATUS}(譯註:PIPESTATUS 保存着管道中各命令的返回值),你應該使用Python。
  • 如果你要編寫一份超過一百行的Shell 腳本,你應該儘量使用Python 來編寫。記住,隨着Shell腳本行數的增長,儘早使用其他語言來重寫你的腳本,以免將來重寫的時候浪費更多的時間。
Continue ->

一键连接VPN

公司安全的同事最近给OpenVPN加上了基于Google Authenticator的二步验证,密码是「常用密码」+「每次变化的Token」,每次在外边想做事都得打开手机查看Token,输入密码串,安全是安全了,可是不能忍!

OSX 生成Token

首先想到的是不要每次都打开手机,所以开始寻找Google Authenticator 生成工具的桌面版,果然有很多解决方案Is there a Google Authenticator desktop client?, 有Web版的、Java版的,不过最高效的当然是命令行版oathtool:

安装oath-toolkit:

brew install oath-toolkit

一个shell脚本,拷贝到 /usr/local/bin/,加上可执行权限:

#!/bin/bash
#fork from http://superuser.com/questions/462478/is-there-a-google-authenticator-desktop-client , by Peter Beckman

scriptname=`basename $0`
if [ -z $1 ]
then
echo "$scriptname: Service Name Req'd"
echo ""
echo "Usage:"
echo "   otp google"
echo ""
echo "Configuration: $HOME/.otpkeys"
echo "Format: name=key"
exit
fi
otpkey=` grep ^$1 $HOME/.otpkeys | cut -d"=" -f 2 | sed "s/ //g" `
if [ -z $otpkey ]
then
echo "$scriptname: Bad Service Name"
exit
fi
token=`/usr/local/bin/oathtool --totp -b $otpkey`
echo $token
echo $token | /usr/bin/pbcopy #自动拷贝至剪贴板
Continue ->