Cygwin 建置
Cygwin 安装
Cygwin 是在 Windows 中一个 POSIX 系统 (例如 Linux),将原本 POSIX 系统中的软件重新编译移植至 Windows。
至 Cygwin Installation 下载 setup-x86_64.exe,将 setup-x86_64.exe 放置于 c:\apps。
由 Cygwin Mirror Sites 得知下载套件的网址 (要拷贝链接或点击才正确),如 Taiwan: ftp.ntu.edu.tw
实际网址为 https://ftp.ntu.edu.tw/pub/cygwin/
。
列出 setup-x86_64 的说明,可运行下列:
c:\apps\setup-x86_64 --help
setup-x86_64.exe 参数简要说明
c:\apps\setup-x86_64 -D -B -l c:\apps\cygwin.pkg -s https://ftp.ntu.edu.tw/pub/cygwin/
-
第 1 页为版本说明。
-
第 2 页应该为 Download Without Installing (只下载不安装)。
-
第 3 页 Local Package Directory 应该是 c:\apps\cygwin.pkg (已缺省好)。
-
第 4 页 Use System Proxy Settings (默认值,不用改)
-
第 5 页 Choose A Download Site 应该是 https://ftp.ntu.edu.tw (已缺省好)。
本步骤仅测试,并不需实际下载,确认参数合乎预期后,可离开安装程序。
安装或下载后,本机套件保存目录中会有 下载网址
的文件夹,如果变更 下载网址
会再创建一个,这表示;如果要重复使用,那么 下载网址
不应变更。
再来,指定安装目录 (-R
) 安装至 c:\apps\cygwin
。
c:\apps\setup-x86_64 -B -R c:\apps\cygwin -l c:\apps\cygwin.pkg -s https://ftp.ntu.edu.tw/pub/cygwin/
-
第 2 页应该为 Install from Internet (下载的文件会保留至本机套件保存目录)。
注:setup-x86_64.exe 选项 -L
由本机套件目录安装,如果没有安装过 Cygwin,那么本机套件并不完整,安装的 Cygwin 无法运行,第一次安装不要采用该方式来安装。
安装或更新时,可采用无人值守安装模式 (-q
) 及指定安装套件 (-P
) 一并安装 openssh,ping,wget,curl,zip,unzip,nano。
注:scp ssh 的套件是 openssh。
c:\apps\setup-x86_64 -q -B -R c:\apps\cygwin -l c:\apps\cygwin.pkg -s https://ftp.ntu.edu.tw/pub/cygwin/ -P openssh,ping,wget,curl,zip,unzip,nano
{ "name" : "Cygwin", "commandline" : "c:/apps/cygwin/bin/bash --login -i", "icon" : "c:/apps/cygwin/Cygwin.ico", "hidden": false },
Cygwin 版本
Cygwin 的版本可由 cygcheck -c cygwin
或 cygcheck -V
得知套件的版本,uname -r
得知 dll 的版本,「套件」跟「dll」的版本应该一致。
运行下列得知 cygwin (套件) 的版本:
cygcheck -c cygwin
Cygwin Package Information
Package Version Status
cygwin 3.4.5-1 OK
运行下列得知 cygwin (套件) 的版本:
cygcheck -V
cygcheck (cygwin) 3.4.5
运行 uname 得知 (dll) 版本:
uname -r
3.4.5-1.x86_64
注:C:\apps\cygwin\bin\cygwin1.dll (/bin/cygwin1.dll) 的版号为 3.4.5
cygwin 是安装测试版:
cygcheck -c cygwin
Cygwin Package Information
Package Version Status
cygwin 3.5.0-0.140.gbf915420042e OK (1)
运行下列得知 cygwin (套件) 的版本:
cygcheck -V
cygcheck (cygwin) 3.5.0
测试版运行 uname 得知 (dll) 版本:
uname -r
3.5.0-0.140.gbf915420042e.x86_64
注:C:\apps\cygwin\bin\cygwin1.dll 的版号为 3.5.0
1 | 当尾码有长编号时,并非表示该套件一定是测试版,运行 setup-x86_64 至 Select Packages 页面,在 New 字段下拉「向下按钮」,在列表中会显示 版号(Test) ,如 cygwin 的 3.5.0-0.140.gbf915420042e(Test) 即为测试版。 |
当更新 cygwin 内核套件时,应关闭 cygwin CLI,如果没有可能会发生「套件」跟「dll」不一致。
- 「套件」跟「dll」不一致时解决方式
-
运行 setup-x86_64 至
Select Packages
页面,在 Search (搜索) 输入cygwin
,在找出的项目cygwin
及cygwin-devel
按下「向下按钮」选取reinstall
,按下 下一步 前要关闭 cygwin CLI。
Cygwin 环境说明
在 Cygwin 的根目录 (/
) 为安装 Cygwin 的路径如 (c:\apps\cygwin
),在 Cygwin 中的 /home
即为 C:\apps\cygwin\home
。
而 ~
表示用户主目录,如用户名为 user
, ~
即为 /home/user
。
在 Cygwin 中的 /usr/bin
比较特殊,Windows 的路径是在 C:\apps\cygwin\bin
。
Cygwin 读取外部目录 (指 Cygwin 安装路径之外),可直接采用 Windows 路径其前后加上单引号 ('
) 或双引号 ("
), 或者以 cygpath 转换成 cygdrive 格式。不过,大部份的命令并不支持 cygdrive 格式,当然也有部份命令不支持双引号只能采用 cygdrive 格式。
比较好的方式,先切换至工作目录 (不在安装路径中,如 D:\MyProject
),在工作目录中以相对路径访问子文件夹,创建的指令档也以相对路径来设置输入或输出。
cygpath 简要说明 (cygpath --help
)
以双引号切换路径:
cd "C:\Windows"
可以看到命令提示列为 Unix 路径
user@MyPC /cygdrive/c/Windows
目前路径转成 Windows 路径:
cygpath -aw .
C:\Windows
主目录转成 Windows 路径:
cygpath -aw ~
C:\apps\cygwin\home\user
取得 Unix 绝对路径:
注:-u 列出 Unix 路径为默认值不需要指定。另外运行 cygpath 时;一般情况不会为「相对」,虽然并不需要 -a 的选项,但建议加入。
cygpath -a "c:\apps\setup-x86_64.exe"
/cygdrive/c/apps/setup-x86_64.exe
以 cygstart 运行 Windows 资源管理器打开目前的文件夹: cygstart . 启动与 .txt 关联的编辑器(例如记事本): cygstart my.txt 注:文件在目前的文件夹。
粘贴 Cygwin 会显示成反白 (Highlighted),非常不习惯改掉它。
查找设置值:
bind -V | grep enable-bracketed-paste
enable-bracketed-paste is set to `on'
暂时取消:
bind 'set enable-bracketed-paste off'
echo "set enable-bracketed-paste off" >> ~/.inputrc
再来重启「终端机」。
修改用户
mkpasswd --local > /etc/passwd
打开 c:\apps\cygwin\etc\passwd 或 nano /etc/passwd
nano 操作简易说明
^O
保存,^X
退出,^W
搜索
注:^
为按下 Ctrl 键。
修改前
winuser:*:197610:197121:U-W10T#winuser#,S-1-5-21-2503564773-1016231635-2146039180-1002:/home/winuser:/bin/bash
修改后
user:*:197610:197121:U-W10T#winuser#,S-1-5-21-2503564773-1016231635-2146039180-1002:/home/user:/bin/bash
如把目前 Windows 的用户 winuser 改为 user。
有两个,一个为帐号 (在前面的位置),一个为用户主目录 (在后面的位置),中间的 winuser 不要动。
存盘后,将主目录 c:\apps\cygwin\home\winuser 改名 c:\apps\cygwin\home\user。
可采用资源管理器或在 cygwin 内运行下列:
mv /home/$(whoami) /home/user
再来重启「终端机」。
改为英文接口及修改命令提示列。
~/.bashrc
打开 C:\apps\cygwin\home\user\.bashrc 或 nano ~/.bashrc
~/.bashrc
# 本行为备注。前置 # 表示为备注。
export TIME_STYLE=long-iso
export LANG="en_US.UTF-8" (1)
export PS1='\n\[\e[0;32m\]cygwin2 \[\e[0;33m\]\w\[\e[0m\]\n\$ '(2)
1 | 改为英文接口,原始为 zh_TW.UTF-8 |
2 | 「命令提示列」缺省为 用户名@计算机名称 ,如果有多个 Cygwin 可修改「命令提示列」,本例为 cygwin2 。 |
套用 bash 环境及配置: source ~/.bashrc 检查一下设置是否正确: echo $TIME_STYLE echo $LANG
Cygwin 的 PATH
缺省会纳入 Windows 的 Path
环境变量。在运行命令时,可能运行 Windows 的运行档,造成混淆,建议将 PATH
限制在 Cygwin 的环境中。
在 Cygwin 检查 PATH:
echo $PATH
/usr/local/bin:/usr/bin:/cygdrive/c/WINDOWS/system32: ...
PATH
是以冒号 (:
) 来区分,主要路径为前二个 /usr/local/bin
、/usr/bin
。
~/.bashrc
重新设置 PATH
及加入其他路径 (如 ~/bin
)export PATH="/usr/local/bin:/usr/bin:~/bin"
export
同等于 Windows 中的 set
,如将变量 myUp
设置为 Windwos 环境变量 %USERPROFILE%
,在 Cygwin 中以 $USERPROFILE
取得。
取得 USERPROFILE 的 Unix 路径: cygpath $USERPROFILE /cygdrive/c/Users/winuser 设置 myUp 变量: export myUp=/cygdrive/c/Users/winuser 切换至 C:\Users\winuser: cd $myUp
export myUp=$(cygpath $USERPROFILE) cd $myUp
myPath=$(cygpath $USERPROFILE) cd $myPath
进入一个子进程: bash 查找 myUp 变量: echo $myUp 回传: /cygdrive/c/Users/winuser 查找 myPath 变量: echo $myPath 并没有回传值,因为 myPath 为临时变量。 PATH 要以 export 来设置,因为子进程共享环境变量。
以 alias 创建指令别名
创建 cup 别名将目前路径切换至 %USERPROFILE%: alias cup="cd $(cygpath $USERPROFILE)" 运行 cup: cup 可以看到命令提示列的路径已切换 user@MyPC /cygdrive/c/Users/winuser
Cygwin bashrc
cat > ~/.bashrc << "EOF"
export TIME_STYLE=long-iso
export LANG="en_US.UTF-8"
export PS1='\n\[\e[0;32m\]'$(basename "$(cygpath -aw /)")' \[\e[0;33m\]\w\[\e[0m\]\n\$'
export PATH="bin:~/bin:/usr/local/bin:/usr/bin:~/node_modules/.bin:/usr/local/npm:/cygdrive/c/apps/nodejs:/cygdrive/c/WINDOWS/system32"
export NODE_PATH="$(cygpath -aw ~/node_modules);$(cygpath -aw /usr/local/npm/node_modules)"
alias code="'$(cygpath "$USERPROFILE\AppData\Local\Programs\Microsoft VS Code\bin\code.cmd")'"(1)
EOF
# 套用 bash 环境及配置
source ~/.bashrc
1 | 加入 VSCode 的别名。 |
注:上述的 .bashrc
虽然会依据 Cygwin 安装路径自动设置 NODE_PATH 的路径,但 npm 的 prefix 并未变更,若要变更运行下列。
设置 prefix 为 /usr/local/npm (由 cygpath 转成 Windows 路径): npm config set prefix "$(cygpath -aw /usr/local/npm)" 检查结果: npm config get prefix
Cygwin ACL
运行 setup-x86_64.exe
以参数 -B
(不以管理员身份运行) 安装 Cygwin。
先设置暂时 PATH:
PATH=$PATH:/cygdrive/c/Windows/System32
列出 Cygwin 根文件夹权限清单:
icacls.exe $(cygpath / -aw)
%USERDOMAIN%\%USERNAME%:(F) %USERDOMAIN%\None:(RX) Everyone:(RX) CREATOR OWNER:(OI)(CI)(IO)(F) CREATOR GROUP:(OI)(CI)(IO)(RX) Everyone:(OI)(CI)(IO)(RX)
刚好有三组 ACE (Access control entry 访问控制项目),上方为文件或文件夹权限,下方为文件夹继承权限。
文件或文件夹权限,F:完整访问权,RX:读取和运行访问权。
getfacl / # file: / # owner: $USERNAME # group: None user::rwx group::r-x other::r-x default:user::rwx default:group::r-x default:other::r-x
getfacl | icacls |
---|---|
|
|
|
|
|
|
观察 Cygwin 创建根文件夹之外文件时 ACL 的情况。
C:\acl-test
并观察权限清单mkdir c:\acl-test icacls.exe C:\acl-test BUILTIN\Administrators:(I)(OI)(CI)(F) NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F) BUILTIN\Users:(I)(OI)(CI)(RX) NT AUTHORITY\Authenticated Users:(I)(M) NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(IO)(M)
该 C:\acl-test
文件夹,Cygwin 的 ACL 跟 Windows 没有对应,缺少了 group
(%USERDOMAIN%\None
),在该文件夹创建文件则 ACL 会出错 (注:写入已创建的文件并不会错误)。
C:\acl-test\acl-file
文件:cd "C:\acl-test"
touch acl-file (1)
1 | 该文件为新档,如果已存在应先删除。 |
acl-file
权限清单,已出错:icacls.exe acl-file
NULL SID:(DENY)(Rc,S,WEA,X,DC)
%USERDOMAIN%\%USERNAME%:(R,W,D,WDAC,WO) (1)
%USERDOMAIN%\None:(DENY)(S,X)
NT AUTHORITY\Authenticated Users:(DENY)(S,X)
NT AUTHORITY\SYSTEM:(DENY)(S,X)
BUILTIN\Administrators:(DENY)(S,X)
BUILTIN\Users:(DENY)(S,X)
%USERDOMAIN%\None:(RX)
NT AUTHORITY\Authenticated Users:(RX,W)
NT AUTHORITY\SYSTEM:(RX,W)
BUILTIN\Administrators:(RX,W)
BUILTIN\Users:(RX)
Everyone:(R)
1 | 权限清单虽然不正确,但拥有者还是有完整的访问权。
R - 唯读访问权 W - 唯写访问权 D - 删除访问权 WO - 写入拥有者 |
acl-file
的 ACL,已出错:icacls.exe acl-file /verify
acl-file: Ace 项目的顺序不标准。
切换至使用主目录后,重建文件 (注:没有重建时 ACL 并不会变更): cd ~ rm "C:\acl-test\acl-file" touch "C:\acl-test\acl-file" 观察权限清单: icacls.exe "C:\acl-test\acl-file" BUILTIN\Administrators:(I)(F) NT AUTHORITY\SYSTEM:(I)(F) BUILTIN\Users:(I)(RX) NT AUTHORITY\Authenticated Users:(I)(M) 检查文件 ACL 是否正确: icacls.exe "C:\acl-test\acl-file" /verify 已处理的文件: C:\acl-test\acl-file (无错误) 以 getfacl 列出文件 ACL: getfacl "C:\acl-test\acl-file" getfacl: C:\acl-test\acl-file: Not supported (不支持)
将 noacl
加入 /etc/fstab
,解决 Cygwin 在根文件夹之外创建文件造成 ACL 错误。
不应让 Cygwin 造成其他文件夹的 ACL 错误,刚安装 Cygwin 就应该加入 noacl
。
noacl
加入 /etc/fstab
cat << EOF > /etc/fstab
none /cygdrive cygdrive binary,noacl,posix=0,user 0 0
EOF
cat /proc/mounts
如下:先检查原状态: cat /proc/mounts C:/apps/cygwin/bin /usr/bin ntfs binary,auto 1 1 C:/apps/cygwin/lib /usr/lib ntfs binary,auto 1 1 C:/apps/cygwin / ntfs binary,auto 1 1 C: /cygdrive/c ntfs binary,posix=0,user,noumount,auto 1 1
检查重启后的状态:
cat /proc/mounts
C:/apps/cygwin/bin /usr/bin ntfs binary,auto 1 1
C:/apps/cygwin/lib /usr/lib ntfs binary,auto 1 1
C:/apps/cygwin / ntfs binary,auto 1 1
C: /cygdrive/c ntfs binary,noacl,posix=0,user,noumount,auto 1 1
cd "C:\acl-test"
rm acl-file
touch acl-file
icacls.exe acl-file (1)
icacls.exe acl-file /verify
getfacl acl-file (2)
1 | 跟文件夹权限一致 (Windows 权限继承)
BUILTIN\Administrators:(I)(F) NT AUTHORITY\SYSTEM:(I)(F) BUILTIN\Users:(I)(RX) NT AUTHORITY\Authenticated Users:(I)(M) |
2 | getfacl: acl-file: Not supported ,「不支持」才是正确的。 |
cat << EOF > /etc/fstab
none /cygdrive cygdrive binary,posix=0,user 0 0
EOF
将 Cygwin 根文件夹 (以 Windows) 拷贝至另一个文件夹 (c:\apps\cygwin-c
)
观察权限清单: icacls.exe "C:\apps\cygwin-c" BUILTIN\Administrators:(I)(OI)(CI)(F) NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F) BUILTIN\Users:(I)(OI)(CI)(RX) NT AUTHORITY\Authenticated Users:(I)(M) NT AUTHORITY\Authenticated Users:(I)(OI)(CI)(IO)(M) 检查 ACL 是否正确: icacls.exe "C:\apps\cygwin-c" /verify /T /Q 已顺利处理 0 个文件; 0 个文件处理失败 (刚开始应该无错误)
进入 cygwin-c
创建根文件夹内的文件时,Cygwin ACL 跟 Windows 没有对应;已知会出错。
创建文件: cd ~ touch acl-file 观察权限清单: /cygdrive/c/Windows/System32/icacls.exe acl-file NULL SID:(DENY)(Rc,S,WEA,X,DC) %USERDOMAIN%\%USERNAME%:(R,W,D,WDAC,WO) %USERDOMAIN%\None:(DENY)(S,X) NT AUTHORITY\Authenticated Users:(DENY)(S,X) NT AUTHORITY\SYSTEM:(DENY)(S,X) BUILTIN\Administrators:(DENY)(S,X) BUILTIN\Users:(DENY)(S,X) %USERDOMAIN%\None:(RX) NT AUTHORITY\Authenticated Users:(RX,W) NT AUTHORITY\SYSTEM:(RX,W) BUILTIN\Administrators:(RX,W) BUILTIN\Users:(RX) Everyone:(R) 检查 ACL 是否正确: /cygdrive/c/Windows/System32/icacls.exe acl-file /verify acl-file: Ace 项目的顺序不标准。
修正 ACL
cygwin-c
在持续使用时,ACL 错误会一直增加。
若需要修正 ACL 错误,可运行下列修正,将 Windows 权限配合 Cygwin 的 Owner、Group、Others,并移除其他权限。
/cygdrive/c/Windows/System32/icacls.exe $(cygpath / -aw) \
/grant \
"$USERDOMAIN\\$USERNAME:F" \
"*S-1-3-1:RX" \(1)
"Everyone:RX" \
"CREATOR OWNER:(OI)(CI)(IO)F" \
"CREATOR GROUP:(OI)(CI)(IO)RX" \
"Everyone:(OI)(CI)(IO)RX" \
/remove \
"NT AUTHORITY\\Authenticated Users" \
"NT AUTHORITY\\SYSTEM" \
"BUILTIN\\Administrators" \
"BUILTIN\\Users" \
"NULL SID" \
/inheritance:r /T /C /Q (2)
1 | S-1-3-1 为 Creator Group ID 即为 $USERDOMAIN\None ,S-1-3-1 参阅: Security identifiers | Microsoft Learn 。 |
2 | inheritance:r :移除所有继承的 ACE,/T :目录下所有文件及文件夹,/C :发生错误时继续运行 (仍会显示错误消息),/Q :(安静运行) 不显示成功消息。 |
检查 Cygwin 根文件夹内所有文件 ACL 是否正确: /cygdrive/c/Windows/System32/icacls.exe $(cygpath / -aw) /verify /T /Q
Ruby
安装 ruby 可采用 setup-x86_64
手动安装或创建 cygpkg 按下列安装
cygpkg install ruby
gem 安装路径
gem env
如下(省略跟安装路径无关的消息):RubyGems Environment:
- INSTALLATION DIRECTORY: /usr/share/gems
- USER INSTALLATION DIRECTORY: /home/user/.gem/ruby/2.6.0
- GEM PATHS:
- /usr/share/gems
- /home/user/.gem/ruby/2.6.0
- /usr/local/share/gems
- GEM CONFIGURATION:
- "gem" => "--user-install --bindir /home/user/bin"
-
一个是安装目录
INSTALLATION DIRECTORY: /usr/share/gems
。
注:实际上还再附加 gems,如/usr/share/gems/gems
。 -
另一个是用户安装目录
USER INSTALLATION DIRECTORY: /home/user/.gem/ruby/2.6.0
。
注:跟上述的注解一样,要附加 gems。
gem install
会安装至「用户安装目录」,也会在 /home/user/bin
创建指令档。~/bin
应纳入 PATH。
采用 bundle
将安装至「安装目录」,并不会在 ~/bin
创建指令档。
更新套件时可能会安装在 /usr/share/gems
。
gem 常用命令
gem search <套件REGEXP> [选项] 「套件REGEXP」表示找出前置合乎「套件名称」的所有套件,除非加入 -e 选项 (全吻合)。 注:套件名称不可含版号。 search 有那些可用选项: gem search -h -a, --all 显示 gem 所有版本 -e, --exact 套件名称全吻合 --prerelease 显示预先发行版本 (注:可简化成 --pre)
gem list
gem list <套件REGEXP> -d 如详细数据中显示 Installed at: /home/user/.gem/ruby/2.6.0 实际安装的路径是在 /home/user/.gem/ruby/2.6.0/gems/套件含版号,如果有更新,会显示多个版本。
gem which <套件> 一般情况,套件的指令档会在套件的安装路径之中,套件的「数据」可能在指令档的上层。多个版本时应采用 which 来得知目前是用那一个版本。
安装 gem-path 套件:
gem install gem-path
运行 gem-path 得知套件安装路径:
gem path <套件>
Node.js
Cygwin 的套件中并没有 NodeJS,但 Windows 平台的 NodeJS 可在 Cygwin 内使用。
安装 NodeJS 由 Download | Node.js 下载 Windows Binary (.zip) 64 bits 解压至 c:\apps\nodejs
。
取得 Unix 路径: cygpath "c:\apps\nodejs" /cygdrive/c/apps/nodejs 检查 nodejs 下载的版本: /cygdrive/c/apps/nodejs/npm -v
-global
) 模块时,先了解 npm 的路径关系。先设置暂时的 PATH 变量
PATH="/usr/local/bin:/usr/bin:/cygdrive/c/apps/nodejs"
显示 prefix 的默认值:
npm config get prefix
C:\apps\nodejs
显示运行档 (bin) 路径:
npm bin -global
C:\apps\nodejs
显示模块路径:
npm root -g
C:\apps\nodejs\node_modules
由上述可知,在 Cygwin 中 npm 运行档 (bin) 路径跟 {prefix}
相同,而模块路径是在 {prefix}/node_modules
,这两者跟 npm-bin | npm Docs 上的说明不同。
Cygwin | npm-bin | npm Docs | |
---|---|---|
packages |
|
|
bin |
|
|
设置 prefix
路径为 /usr/local/npm
,由于 NodeJS 是 Windows 平台,需要以 Windows 的路径来设置 prefix
及 NODE_PATH
。
在 Cygwin 一定要设置 NODE_PATH
,命令 node
才能找到全局模块,另外;运行 node
的命令是子进程,要以 export
来设置 NODE_PATH
。
设置 prefix 为 /usr/local/npm (由 cygpath 转成 Windows 路径):
npm config set prefix "$(cygpath -aw /usr/local/npm)"
检查结果:
npm config get prefix
C:\apps\cygwin\usr\local\npm
显示模块路径:
npm root -g
C:\apps\cygwin\usr\local\npm\node_modules
显示运行档 (bin) 路径:
npm bin -g
C:\apps\cygwin\usr\local\npm
npm ERR! bin (not in PATH env variable)
提示运行档没有纳入 PATH 变量。
列出 .npmrc 的内容:
cat ~/.npmrc
prefix=C:\apps\cygwin\usr\local\npm
在指定的路径 (locally 本地) 中安装模块时,如用户主目录 (~),则会在该目录中创建两个文件 package.json
及 package-lock.json
(注:全局没有这些文件),模块保存在 ~/node_modules
,运行档路径为 ~/node_modules/.bin
。npm root
及 npm bin
刚好就是主目录路径,但那不重要,主要是以 NODE_PATH
及 PATH
为准,如果只是引用函数库并不需要将 ~/node_modules/.bin
纳入 PATH
。
在「本地」路径安装模块之前,先在本地运行初始化 npm init -y
,如果没有初始化;则 npm 会自动找出上层的模块设置档 (package.json
),并将模块安装在上层。注:主目录 ~
上层并不会安装 npm 模块,可不需要初始化。
npm 维护模块时如 install
、uninstall
、update
、list
,区分「本地」及「全局」,本地安装 (install) 时需将目前路径切换至「本地」,本地安装则以本地移除 (uninstall),本地移除时并不会移除全局。
node 在运行 .js
时,会先找出该文件路径或 (所有的) 上层路径是否有 node_modules
子目录,如果有则会加载 node_modules
内的模块 (不需要设置 NODE_PATH
)。
当 .js
文件在不同的路径中则要设置 NODE_PATH
(该设置值有顺序,本地路径要在全局之前)。
何种情况,需要在本地路径中安装模块?
如安装旧版的模块时,最好不要以全局安装,全局模块应为最新的模块,旧版的模块应该安装在本地,避免全局模块在安装或更新时,自动更新。
~/.bashrc
如下添加(或修改)export PATH="/usr/local/bin:/usr/bin:~/node_modules/.bin:/usr/local/npm:/cygdrive/c/apps/nodejs
export NODE_PATH="C:\apps\cygwin\home\user\node_modules;C:\apps\cygwin\usr\local\npm\node_modules"
|
安装模块。 |
|
移除模块。 |
|
显示已安装的模块。 |
|
更新模块及相依模块至最新版本。 |
|
检查可安装模块的 (最新) 版本。 |
|
检查可安装模块的所有版本。 |
|
查找可安装的模块的信息,如版本、相依模块等 (JSON)。 |
|
搜索可安装模块。 |
|
列出组态。 |
|
列出所有组态。 |
相关网页:
npm Docs
cygpkg 套件安装移除及更新
在 cygwin 主控台 (CLI) 中运行套件安装移除及更新,交由 setup-x86_64.exe 来维护, 下载套件时于脚本指定下载网站及指定保存于本机 (共享) 套件目录。
bind "set disable-completion on"
bash -c 'cat > /usr/local/bin/cygpkg' << "EOF"
#!/bin/bash
usage="Usage: ${0##*/} operation [package(s)]
OPERATIONS:
i, install Install package(s).
r, remove Remove package(s).
u, update Update package(s), display the installer, and update manually.
f, fix Update packages to the current release version."
ExecuteFile='c:\apps\setup-x86_64.exe'(1)
params='-l "c:\apps\cygwin.pkg" -s https://ftp.ntu.edu.tw/pub/cygwin/'(2)
UpdatePkgs=0
case "$1" in
i|install)
params="${params} -q -P";
shift;
pkgs=$@;;
r|remove)
params="${params} -q -x";
shift;
pkgs=$@;;
u|update)
UpdatePkgs=1;
params="${params} -M";
shift;
pkgs=$@;;
f|fix)
UpdatePkgs=1;
params="${params} -f -M";
pkgs='';;
-h|--h*) echo "$usage"; exit 0;;
-*|--*) echo "unknown option: $1" >&2; exit 1;;
*) echo "$usage"; exit 0;;
esac
pkgs=${pkgs//,/ }
pkgs="$(echo $pkgs)"
pkgs=${pkgs// /,}
if [ $UpdatePkgs -ge 1 ]; then
if [[ -n "$pkgs" ]]; then
pkgs="-P ${pkgs}"
fi
elif [[ -z "$pkgs" ]]; then
echo "$usage"
exit 1
fi
if [ -f /var/log/setup.log ]; then
logsize=$(stat -c%s /var/log/setup.log)
let MaxSize=10*1024*1024
if [ $logsize -gt $MaxSize ]; then
echo "The /var/log/setup.log ("$(numfmt --to=iec $logsize)") is larger than 10M, it seems abnormal,"
read -p "Do you want to delete it? (Y/N): " yn
if [ "${yn}" != "Y" ] && [ "${yn}" != "y" ]; then
exit 1
fi
set -e
rm /var/log/setup.log
touch /var/log/setup.log
set +e
fi
fi
show_size() {
if [ -f /var/log/setup.log ]; then
logsize=$(stat -c%s /var/log/setup.log)
else
logsize=0
fi
echo -e "\nThe size of /var/log/setup.log is "$(numfmt --to=iec $logsize)"."
exit
}
if [[ -n "$pkgs" ]]; then
cmdline="'$(cygpath -a "$ExecuteFile")' -B -d -n -N --no-write-registry -R \"$(cygpath -aw /)\" ${params} ${pkgs}"
echo $cmdline
trap show_size INT
echo -e "\033[1;33mNotice! When specifying a package, do not select Cygwin core in the installer to update.\033[0m"
eval $cmdline
show_size
else
cmdline="cygstart CMD '/K (\"$ExecuteFile\" -B -d -n -N --no-write-registry -R \""$(cygpath / -aw)"\" ${params})'"
echo $cmdline
echo -e "\033[1;33mWhen updating the Cygwin core, you must exit the Cygwin CLI.\033[0m"
eval $cmdline
fi
EOF
bind "set disable-completion off"
chmod +x /usr/local/bin/cygpkg
1 | setup-x86_64.exe 的全路径。 |
2 | 本机套件保存目录及指定下载网站,注意 -l "c:\apps\cygwin.pkg" 要双引号。 |
安装套件:
cygpkg install zip,unzip,nano
或以空白区分套件:
cygpkg install zip unzip nano
移除套件:
cygpkg remove zip,unzip,nano
显示套件更新(未指定套件,以 cmd 进程运行):
cygpkg update
套件更新 (或安装指定版本):
cygpkg update gcc-g++=7.4.0-1
setup-x86_64.exe
) 更新 Cygwin core (内核),更新时会出现下列消息:io_stream_cygfile: fopen(/usr/bin/cygwin1.dll) failed 13 Permission denied Failed to open cygfile:///usr/bin/cygwin1.dll for writing. running: c:\apps\cygwin\bin\kill.exe -TERM -W 10124 [处理结束,代码为 4294967295 (0xffffffff)]
因为更新 Cygwin core 会终止 Cygwin CLI 进程,为正常现像。但有时不会运行「终止」,则可能会造成 /bin/cygwin1.dll
的版本不一致,在更新内核时,应退出 Cygwin CLI。若版本已不一致,解决方式可参阅 Cygwin 版本。
有指定套件时,如 cygpkg u nano
不应选取 Cygwin core,在指定套件的情况下 cygpkg 并未以 cmd 进程来运行,运行更新后 Cygwin 将会崩溃。
bash: /usr/bin/locale: No such file or directory bash: /usr/bin/tzset: No such file or directory
cygpkg f
JavaScript 套件
JSHint
JSHint 检查 JavaScript 错误,如以建议 === 或 !== 以避免转型、变量没有以 var 声明、陈述式结尾没有加分号。 刚学 JavaScript,范例以浏览器测试是正确,可是采用 JSHint 检查后才发觉函数不存在 …。
把 JavaScript 粘贴 JSHint 可即时检查出错误。
npm install -global jshint
cd $docs
jshint $InputFile
如出现 Something is available in ES6,表示 JavaScript 使用了 ECMAScript 6,那它会不会太新?
ECMAScript - 维基百科,自由的百科全书
jshint -v
# jshint v2.12.0 (1)
1 | JSHint Blog 只会在某个版本说明, New Release: 2.10.0 : support for the three most recent editions of JavaScript: ES7, ES8, and ES9. |
那如何设置让 JSHint 检查的 ES 版本;可参考 JSHint Documentation ,实测顺序如下。 另外选项可参考 JSHint Options Reference 。
-
.js
加入/* jshint esversion:5, maxdepth:1 */
-
--config
参数指定设置档 -
.jshintrc
设置档 (跟 .js 相同的目录),可按照 jshint/.jshintrc at master · jshint/jshint · GitHub 来设置。
'jQuery' is not defined.
{ // https://github.com/jshint/jshint/blob/master/examples/.jshintrc ... "yui": false, // Yahoo User Interface // Custom Globals "globals": { "jQuery": true // 加入 jQuery } // additional predefined global variables }
陈述式结尾没有加分号时采用下列自动修正
cd $docs
cat > bin/fixJsFile << "EOF"
#!/bin/sh
for i in `jshint $1 | grep -i "Missing semicolon" \
| sed -e 's/\([^0-9]*\)\([0-9]*\)\(.*$\)/\2/'`;
do
echo 修复文件:$1 行号: $i
sed -i $1 -e $i's/\(\s*\)$/;/'
wait
done
EOF
fixJsFile $InputOutputFile
terser
GitHub - terser/terser: JavaScript parser, mangler and compressor toolkit for ES6+
JavaScript 压缩,代码缩小化 (变量名称缩减、去掉注解、空白字符、换行字符 …),去掉 console.log …
npm install -global terser
terser --version
# terser 5.3.4
# 测试,结果显示主控台
terser $InputFile -c drop_console,passes=2 -m (1)
1 | 参考官方网页:-c drop_console 去掉 console.log,passes=2 运行 2 次压缩,-m 变量名称缩减。 |