理解腳本
如果你打開一本 JavaScript 教程,那么很可能在第一章就看到這句話:
JavaScript 是一門動態(tài)類型、面向?qū)ο蟮哪_本語言。
然而很多前端工作一年都不清楚這個腳本是什么意思。
其實腳本原本來自戲劇舞臺,比如下面這個腳本:
公館一室內(nèi)
王媽:(小心翼翼地)小姐,您還是得注意身子,就吃點東西吧。
雞小姐:(把碗砸在地上)不吃,我就是不吃。
(王媽下)
腳本主要由人物對話和舞臺提示組成。演員和道具組只需要按照腳本說的做即可。
編程領(lǐng)域的腳本也是類似的,計算機(jī)只要照著腳本上說的做即可,比如下面這個腳本:
cd ~/Desktop
mkdir demo
cd demo
echo "hi" > index.html
cd ~/Desktop
所以說,腳本就是給計算機(jī)照著做的。這是我們對「腳本」的一個感性認(rèn)識。接下來我們寫一個腳本。
寫一個腳本
-
找個地方新建文件,后綴隨意,一般來說腳本的后綴是 .sh,但是我偏要把后綴寫成 .txt。我喜歡把腳本放在 ~/local 目錄里。(我知道你沒有這個目錄,創(chuàng)建一下這個目錄就行啦)
mkdir ~/local-
cd ~/local請一定要運(yùn)行這句話!如果不運(yùn)行,那么下面所有步驟都會出錯 touch demo.txt
-
編輯 demo.txt,內(nèi)容如下:
pwd # 確認(rèn)一下當(dāng)前路徑是不是 ~/local 或者 /c/Users/你的名字/local mkdir demo cd demo mkdir css js touch index.html css/style.css js/main.js exit (Windows 用戶請?zhí)^這一步)給 demo.txt 添加執(zhí)行權(quán)限
chmod +x demo.txt-
在任意位置執(zhí)行
sh ~/local/demo.txt即可運(yùn)行此腳本cd ~/Desktopsh ~/local/demo.txt- 你會看到當(dāng)前目錄里多出一個 demo 目錄,demo 目錄里面還有一些文件
好了,這個 demo.txt 就是你寫出的第一個 Bash 腳本了。
-
將 ~/local 添加到 PATH 里
-
cd ~/local; pwd得到local的絕對路徑 - 臨時設(shè)置 PATH
- 運(yùn)行
export PATH="local的絕對路徑:$PATH",這句話是把 local 目錄加到 PATH 里,注意替換local的絕對路徑 - 這時你只要運(yùn)行
demo.txt就相等于運(yùn)行sh ~/local/demo.txt了(你可能會看到 File exists 的報錯,不用管它)
- 運(yùn)行
- 永久設(shè)置 PATH,上面的 PATH 在你重啟 Bash 之后就會失效,如果你希望 PATH 一直生效,看下面
- 創(chuàng)建 ~/.bashrc:
touch ~/.bashrc - 編輯 ~/.bashrc:
start ~/.bashrc - 在編輯器里添加一行字:
export PATH="local的絕對路徑:$PATH"- 有些同學(xué)居然不知道 local的絕對路徑 是什么,我真是服了,前面的都白講了
- 想要知道 local的絕對路徑,只需要:
- 進(jìn)入 git bash
cd ~/localpwd- 打印出來的東西就是 local的絕對路徑!
- source ~/.bashrc
- 之前你要運(yùn)行
sh ~/local/demo.txt,現(xiàn)在你只需要運(yùn)行demo.txt(注意不是demo,是demo.txt啊同學(xué),幾十個同學(xué)都看成demo了,眼睛是不是瞎了……)就行了
- 創(chuàng)建 ~/.bashrc:
-
-
如果你覺得 demo.txt 的后綴 .txt 沒什么用,可以用下面的命令刪掉它
mv ~/local/demo.txt ~/local/demo- 現(xiàn)在你只要運(yùn)行
demo就能執(zhí)行該腳本了。 - 但是如果你沒有運(yùn)行過
mv ~/local/demo.txt ~/local/demo,就必須用 demo.txt 才能執(zhí)行 demo.txt(看起來是廢話,但是很多學(xué)生都沒發(fā)現(xiàn))
細(xì)節(jié)
- PATH 的作用
你每次在 Bash 里面輸入一個命令時(比如 ls、cp、demo),Bash 都會去 PATH 列表里面尋找對應(yīng)的文件,如果找到了就執(zhí)行。 - 使用 type demo 可以看到尋找過程
- 使用 which demo 可以看到尋找結(jié)果
- 文件后綴的作用:毫無作用
你以為一個文件以 .exe 結(jié)尾就一定可以雙擊嗎?你以為一個文件以 .png 結(jié)尾就一定是圖片嗎?圖樣圖森破!
參數(shù)
demo 腳本只能創(chuàng)建名字為 demo 的目錄,太無聊了,我們讓目錄名是可變的吧。
mkdir $1
cd $1
mkdir css js
touch index.html css/style.css js/main.js
exit
$1 表示你傳的第一個參數(shù)。
老師你怎么知道 $1 表示第一個參數(shù)?
好問題,答案是
我 Google 出來的 http://lmgtfy.com/?q=bash+first+param
用百度也行 http://www.baidu-x.com/?q=bash+%E7%AC%AC%E4%B8%80%E4%B8%AA+%E5%8F%82%E6%95%B0
判斷目錄是否已存在
if [ -d $1 ]; then
echo 'error: dir exists'
exit
else
mkdir $1
cd $1
mkdir css js
touch index.html css/style.css js/main.js
echo 'success'
exit
fi
老師,你怎么知道 -d $1 可以判斷目錄是否存在?
我 Google 出來的 http://lmgtfy.com/?q=bash+dir+exists
返回值
-
exit 0表示沒有錯誤 -
exit 1表示錯誤代碼為 1
demo && echo '結(jié)束'
只有在 demo 成功時,才會執(zhí)行 echo '結(jié)束'
思考題
我們創(chuàng)建的 index.html style.css 和 main.js 都是空文件,如何給他們填充內(nèi)容呢?
Node.js 寫腳本
上面我們寫的腳本叫做 Bash Script(Bash腳本)。
JS 的全稱叫做 JavaScript(Java腳本),雖然 JS 和 Java 沒什么關(guān)系,但是 JS 依然是一種腳本。
- 我們在 Bash 命令行里輸入 Bash 命令,也可以在 Node.js 命令行里輸入 JS 命令(<kbd>Ctrl</kbd> + <kbd>D</kbd> 退出)
- Bash 腳本能做的事情,JS 腳本也能做。(
sh demo.sh對應(yīng)node demo.js)
用 JS 切換目錄
console.log(process.cwd()) // 打印當(dāng)前目錄
// process.chdir('~/Desktop'); // 這句話不行的,因為 JS 不認(rèn)識 ~ 目錄
process.chdir("/Users/frank/Desktop")
console.log(process.cwd()) // 打印當(dāng)前目錄
console.log 就相當(dāng)于 echo
用 JS 腳本創(chuàng)建目錄
Google nodejs create dir
文檔:https://nodejs.org/api/fs.html#fs_fs_mkdirsync_path_mode
let fs = require("fs")
fs.mkdirSync("demo")
用 JS 腳本創(chuàng)建文件
Google nodejs create file
文檔: https://nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_options
let fs = require('fs')
fs.writeFileSync("./index.html", "")
用 JS 腳本來重寫 demo.sh
-
創(chuàng)建 ~/local/jsdemo.js,內(nèi)容如下
var fs = require('fs') var dirName = process.argv[2] // 你傳的參數(shù)是從第 2 個開始的 fs.mkdirSync("./" + dirName) // mkdir $1 process.chdir("./" + dirName) // cd $1 fs.mkdirSync('css') // mkdir css fs.mkdirSync('js') // mkdir js fs.writeFileSync("./index.html", "") fs.writeFileSync("css/style.css", "") fs.writeFileSync("./js/main.js", "") process.exit(0) (Windows 用戶跳過這一步)給 jsdemo.js 加上執(zhí)行權(quán)限
chmod +x ~/local/jsdemo.jscd ~/Desktopnode ~/local/jsdemo.js zzz,就可以看到 zzz 目錄創(chuàng)建成功了
shebang
我們每次執(zhí)行 ~/local/jsdemo.js 都要用 node 來執(zhí)行,能不能做到不加 node 也能執(zhí)行呢(也就是指定執(zhí)行環(huán)境),可以,在 jsdemo.js 第一行加上這一句即可:
#!/usr/bin/env node
(以下操作在 Windows 上可能失敗,失敗了就算了)
- 然后你就可以直接用
~/local/jsdemo.js zzz了(省得輸入 node 了)。 - 如果你已經(jīng)把 ~/local 加入了 PATH,那么甚至可以直接輸入
jsdemo.js zzz來執(zhí)行。 - 如果你再把 jsdemo.js 的后綴 .js 去掉,就可以直接
jsdemo zzz了。
注意,你每次執(zhí)行前最好刪掉 zzz 目錄,以免發(fā)生沖突。
總結(jié)
- 腳本就是給機(jī)器一行一行執(zhí)行的文本
- Bash 腳本有 Bash 腳本的語法,Node.js 腳本有 JS 語法
- 不管是那種腳本,能實現(xiàn)的功能都差不多,只是語法不同
- Bash 腳本的語法挺奇葩的,比如
# 等符號
- 不用特別去學(xué) Bash 腳本的用法,遇到不會的就 Google
- 不用特別去學(xué) Node.js 腳本的用法,遇到不會的就 Google
- 新人寫代碼最大的問題就是「抄錯了」
- 多寫了一個空格
- 少寫了一個空格
- 單詞拼錯了
- 沒有加分號
- 多加了分號