【实现】树莓派开机自动向微信发消息报告ip地址(无第三方代理)
可能不少有樹莓派的小伙伴都遇到過這樣一個問題,長期不用但已經配置過的樹莓派,剛開機會自動連接已經識別的wifi,如果沒有wifi的管理密碼,手頭又沒有可以顯示的設備,手邊也沒有能讀tf卡的機器,就只能面對默默亮燈的樹莓派望洋興嘆了。
如果能在每次樹莓派開機的時候自動獲取連接的ip地址,并發送到自己的微信上,豈不是快捷又方便?就像這樣 ↓ ↓ ↓ ↓↓↓ ↓↓↓ ?(。???。)?
怎么實現呢?Please follow me~
文章目錄
- 1. 思路(可行性分析):
- 2. 獲取ip地址
- 3. 注冊企業微信號(無門檻)
- 4. 調用api發送信息
- 4.1 新建應用
- 4.2 記住幾個關鍵信息
- 4.3 獲取access_token
- 4.4 發送信息
- 4.5 賦予文件可執行權限并執行編寫的腳本
- 5. 設置開機自動運行
- 6. 重啟自動執行不成功?
- 6.1 添加環境變量,使cron開機能成功執行腳本
- 6.2 添加循環判斷,在未連接時不斷檢測,連接后發送消息
- 7. 成功!
- 8. 關于IP地址獲取的改進
- 9.附:完整示例代碼:
1. 思路(可行性分析):
- 通過樹莓派shell命令,可以獲取ip地址
- 通過crontab定時任務功能,可實現開機執行特定腳本
- 企業微信號注冊很方便,提供群發api接口,只需注冊一個企業微信號,成員只有自己一個人,調用api接口可以向自己發送消息
so,完全可以很方便的實現~
2. 獲取ip地址
這個應該是最簡單的一步了吧,為了防止后面我忘了,就寫在前面吧。
ifconfig命令可以查看網絡連接狀態,用|grep 192.168篩選其中包含192.168的信息(畢竟我們只需要這個192.168.x.x的地址),再用|awk -F net '{print $2}'選擇其中第一個地址,就是我們樹莓派連接的ip地址了。
即:ifconfig|grep 192.168|awk -F net '{print $2}'
ifconfig命令執行后包含192.168.x.x的信息應該只有兩處,第一處是我們要用的ip地址inet,第二處則是broadcast。這兩個信息都是在一行展示,所以用grep篩選后會是如下形式:
inet 192.168.1.4 netmask 255.255.255.0 broadcast 192.168.1.255
所以我們要再用awk的截取操作,我們發現要提取的ip地址處于兩個“net”字符之間,因此我們設置截取的分隔符為“net”,則會將這段信息截成三部分,第一部分是"i",第二部分是"192.168.1.4",第三部分是"mask 255.255…",我們要取的是第二部分,因此print $2
?
- awk使用格式為:|awk -F 分隔符 '{命令}'
- grep使用格式為:|grep 篩選內容
3. 注冊企業微信號(無門檻)
點擊進入→:企業微信官網
按要求注冊就行了,沒有任何門檻,非常簡單,略過不提。
4. 調用api發送信息
4.1 新建應用
在“應用管理>應用>自建”一欄中點擊“創建應用”,根據提示創建一個應用即可。如圖:
4.2 記住幾個關鍵信息
- 應用ID(AgentId)
- 秘鑰(Secret) (以上兩個均可點進剛才創建的應用列表里找到)
- 企業ID(corpID) (在“我的企業>企業信息”最下方找到“企業ID”)
然后我們在樹莓派上一個方便的目錄下,創建一個.sh文件,比如叫作 AutoDetectIP.sh
打開編輯,首行按規矩先輸入:
回車換行,然后我們將上述信息賦值成變量:
AgentId=xxxxx Secret=xxxxx corpId=xxxxx注1: shell賦值時等號左右不能空格!
注2: 調用時要在變量前面加“$”,如輸出AgentId:echo $AgentId
4.3 獲取access_token
需要用 get 方式請求網址,命令格式如下:
curl https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
其中ID和SECRET分別填寫上面記住的企業ID和秘鑰
curl請求時,不加參數默認就是get請求,后面直接跟網址即可。
調用前面的變量,于是命令為:
curl https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$corpId&corpsecret=$Secret
如果正確,會返回一串信息,其中包含我們需要的access_token和其生效時間。
我們可以把這段信息賦值給一個變量temp,于是命令又進一步改為:
在shell腳本中反引號 ` 括起來的內容表示這是一段命令而不是字符串,也可以用$()括起來,但最好用前者。
- 注意: 要區分 $(命令) 和 ${變量}
這時temp中內容就包含了我們的access_token,接下來要截掉多與信息,依然使用前面提到的|awk操作:
觀察所給信息格式,大致如下:
如果錯誤,返回格式大致為:
{"errcode":40001,"errmsg":"invalid credential, hint: [16051035.........], from ip: 111...., more info at https://open.work.weixin.qq.com/devtool/query?e=40001"}
如果正確,返回格式大致為:
{"errcode":0,"errmsg":"ok","access_token":".........................","expires_in":7200}
我們可以將連續的雙引號、冒號、雙引號,即 “:” 作為分隔符,如果錯誤則只能得到2部分,如果正確則能得到3部分。且第三部分中如果我們再以 “,” 作為分隔符,則其中的第一部分就是純凈的access_token。因此,我們借助條件語句,代碼如下:
if [ -n `echo $temp|awk -F \":\" '{print $3}'` ];thenaccess_token=`echo $temp|awk -F \":\" '{print $3}'|awk -F \",\" '{print $1}'` fi- 如果上述命令直接在控制臺或要寫成一行輸入,則 fi 前面必須加分號;
- if 后的判斷框[ ]和里面的條件語句必須左右留有一個空格,即 [ 的右邊和 ] 的左邊必須空一格
- 參數 -n 表示如果參數長度不為0,則執行then,否則執行else(shell中如果else下沒有命令就不能寫,不可命令留空);相反,參數 -z 表示如果參數長度為0,則執行then,否則執行else
- 雙引號前面要加轉義符 \
至此,我們得到了access_token并將其存入了變量access_token中。
4.4 發送信息
需要用post方式請求網址,并用json傳遞結構化參數:
官方文檔給出的參數示例為:
post地址為:https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN
(ACCESS_TOKEN為剛獲取到的內容)
將地址賦值給變量(要不然之后的命令太長了):
用curl進行post請求,并以json傳遞參數,格式為:
curl -H "Content-type: application/json" -X POST -d ‘{參數}’ 網址
其中,參數內容中如果要引用變量,需要先用雙引號,再用單引號,再用雙引號括起來,然后$變量名,例如:
-X POST -d '{"touser":"@all","msgtype":"text","agentid":"'"$AgentId"'","text",{"content":"IP地址為'"$IP"'"}}'參數中,msgtype、agetid、text、content是必須包含的參數,touser、toparty、totag三者至少需要包含一個
(IP變量沒定義的記得先定義,方法如第2節所述命令,格式如前述:變量名=$`命令` <反引號括起來的都是命令>)
故發送消息命令為:
curl -H "Content-type: application/json" -X POST -d '{..如上..}' $PostURL保存退出。
4.5 賦予文件可執行權限并執行編寫的腳本
賦予權限:
sudo chmod +x AutoDetectIP.sh
+號代表賦予權限,-號代表剝奪權限,x表示可執行權限,r表示可讀權限,w表示可寫權限
執行腳本文件:
./AutoDetectIP.sh
默認用bash執行,執行時默認檢查的是/etc、/bin等這些文件夾,一般我們用戶操作的文件夾都不再檢查范圍內,所以要用 ./ 來強調從本文件夾中查找文件并執行(當然,得先進入文件夾,或者輸入完整路徑)
出現如下提示且手機收到消息(需要提前掃描企業二維碼關注企業,二維碼在“我的企業>微信插件>邀請關注”中),則發送成功。
% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed 100 277 100 277 0 0 601 0 --:--:-- --:--:-- --:--:-- 602 {"errcode":0,"errmsg":"ok","invaliduser":""}5. 設置開機自動運行
我們使用crontab定時任務功能來實現。
在控制臺終端輸入
crontab -e
即可啟動定時任務配置文件,第一次配置會提示選擇編輯器,選擇你習慣的編輯器或者直接回車也ok,即可進入文件進行配置,文件默認注釋部分就是說明和示例,可以創建每隔多久運行一次的任務,只需按規則在文件后添加即可,且保存后如果機器重啟,定時任務仍然有效。
格式為:
如:
0 0 * * * /home/pi/backup.sh 表示每天00:00運行備份程序
*/5 * * * * python /home/pi/test.py 表示每5分鐘用python運行一次test.py程序
0 5 * * 1 sudo apt-get update -y; sudo apt-get upgrade -y 表示每周一天05:00時更新apt軟件包
- 星號(*):代表所有可能的值,例如month字段如果是星號,則表示在滿足其它字段的制約條件后每月都執行該命令操作;
- 逗號(,):可以用逗號隔開的值指定一個列表范圍,例如,“1,2,5,7,8,9”;
- 短橫(-):可以用在整數之間表示一個范圍,例如“2-6”表示“2,3,4,5,6”;
- 斜線(/):可以用正斜線指定時間的間隔頻率,例如h位置處填“0-10/2”表示0點到10點間每兩小時執行一次。同時斜線可以和星號一起使用,例如*/10,如果用在m位置,表示每十分鐘執行一次。
如果想要每次開機執行任務,只需在文件最后添加:
@reboot /home/pi/AutoDetectIP.sh
這里面需要根據你之前創建文件的位置輸入完整路徑,即表示每次開機自動運行此文件
保存退出即可。
6. 重啟自動執行不成功?
到這里可以說基本已經全部完成了。可能有的小伙伴興沖沖地重啟樹莓派,滿心期待的望著手機,結果卻發現等了個寂寞。。。
怎么回事呢?
如果檢查sudo service cron status確定cron計時任務正在運行的話,那么主要有兩個原因:
因此,針對這兩種情況我們分別進行調整。
6.1 添加環境變量,使cron開機能成功執行腳本
首先我們要確定在當前用戶執行成功時,腳本所用到的環境變量。
我們可以在腳本末尾添加一行代碼:(調試成功后記得刪掉)
echo $PATH
再次運行,就可以得到當前運行所使用的環境變量,比如我的為:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games
那么我們只需把這些環境變量手動添加到腳本中即可。
在腳本正文的第一行(在#!/bin/bash之下)添加如下代碼即可:
6.2 添加循環判斷,在未連接時不斷檢測,連接后發送消息
我們使用shell腳本中的while循環語句:
while true; do (echo `ifconfig|grep 192.168`)&& break;sleep 1;done;如上,表示不斷循環,直到匹配192.168的內容非空時,跳出循環,循環間隔1s。
我們將此句加入腳本文件中合適位置,就可以在運行后一直等待連接網絡成功的第一時間向微信發送消息。(此句至少得放在所有使用curl這樣與網絡相關的命令之前)
其次,為了保證啟動時程序不影響其他啟動內容,或不被系統過快切斷,因此我們將crontab中的命令修改為nohup + 命令+ &這樣的靜默不掛起運行方式:
控制臺輸入crontab -e進入編輯定時任務,將原來的命令修改為:
7. 成功!
至此,所有步驟都結束了。我們就可以在每次樹莓派開機時,通過微信自動收到所連接的ip地址消息提示了。
8. 關于IP地址獲取的改進
上面關于本機IP地址的操作主要有兩個,一是通過是否包含“192.168”字段來判斷是否連接wifi,二是通過|grep、|awk等操作截取純凈的ip地址信息。
其中第一個判斷方式應該來說是較為準確且穩定的,符合我們的使用目標。
但第二個提取操作卻有可能因為網絡環境的變化,或網絡設置的調整,可能會有字段的位置或是中間內容的調整,使得截取出來的不一定再是純凈的ip地址。因此我們可以更換一種更為快捷的獲取IP地址的方式:
hostname -I很簡單的命令不用任何操作,就可以直接輸出樹莓派所連接的ip地址。
當然,如果你連接的網絡給你分配了ipv6地址的話,也會一并展示出來,如果需要再按需提取即可。比如我的輸出如下:
如果只需要提取前面的ipv4地址,那么同上用awk截取:
echo `hostname -I|awk -F ' ' '{print $1}'`如果要賦值給變量$IP,那么用內外雙重反引號會造成歧義,故可以在外面用$(命令)的方式:
IP=$(echo `hostname -I|awk -F ' ' '{print $1}'`)如此即可提取出純凈的ipv4地址
最終效果如圖:
?
?
?
?
9.附:完整示例代碼:
#!/bin/bash ########################################### ##### created by RichardYann ##### ##### 2020-11-11 ##### ##### EmaiL:yanrichard500@gmail.com ##### ############################################ set PATH export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games"# Global Variables corpid=CORPID # change to your own corpid AgentId=AGENTID # change to your own agentid Secret=SECRET # change to your own secret getTokenURL="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$corpid&corpsecret=$Secret"# check netstat while true; do $(echo `ifconfig|grep 192.168`)&& break;sleep 1;done;# get token temp=`curl $getTokenURL` if [ -n `echo $temp|awk -F \":\" '{print $3}'` ];thenaccess_token=`echo $temp|awk -F \":\" '{print $3}'|awk -F \",\" '{print $1}'` fi# get postURL PostURL="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=$access_token"# get ip; change $1 to $2 if you wanna get ipv6 addr.(if you had) IP=$(echo `hostname -I|awk -F ' ' '{print $1}'`)# send post curl -H "Content-type: application/json" -X POST -d '{"touser":"@all","msgtype":"text","agentid":"'"$AgentId"'","text":{"content":"樹莓派已經啟動啦!!\n\nIP地址是:'"$IP"'\n\n快點連接控制吧~~"},"safe":0}' $PostURL總結
以上是生活随笔為你收集整理的【实现】树莓派开机自动向微信发消息报告ip地址(无第三方代理)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度解析UG二次开发装配的部件事件、部件
- 下一篇: 古诗接力