ash 中的别名 - 限制、语法问题?

ash 中的别名 - 限制、语法问题?

我在 NAS (WD-MBL) 中运行 OpenWRT,并组合一组别名,以便通过命令行更轻松地进行维护。

这些按预期工作:

alias shutdown='sync && wait && sudo hdparm -Y /dev/sda && wait && sudo halt'

正常关闭 NAS。

daemon='sudo /etc/init.d/rsyncd status'

告诉我rsync守护进程的状态。

drivechk='sudo dmesg | grep -i ext4-fs | grep -i sda'

提醒我由于错误关闭而导致的文件系统问题,需要e2fsck.

tempchk='sudo smartctl -d ata -A /dev/sda | grep Temperature | cut -c 5-8,87-89'

告诉我驱动器温度。

但有一个我无法开始工作:

fschk='df -h | grep -vE '^Filesystem|/dev/root|tmpfs'| awk '{ print $5 " " $1}'

从命令行运行的节按预期工作:

~$ df -h | grep -vE '^Filesystem|/dev/root|tmpfs'| awk '{ print $5 " " $1}'
53% /dev/sda1
37% /dev/sda3
~$

如果我将其添加到/etc/profile.d/custom.sh文件中,注销并再次登录,我会在终端上看到以下内容:

~$ ssh [email protected]
--- snip ---
BusyBox v1.33.2 (2022-02-16 20:29:10 UTC) built-in shell (ash)

alias:  }' not found

~$ 

如果我然后运行别名,我会得到:

~$ fschk
> 

如果我alias从命令行查询列表,我会发现我添加的列表在打印输出中显示不同:

~$ alias
--- snip ---
fschk='df -h|grep -vE '"'"'^/dev/root|tmpfs'"'"'|awk '"'"'{print  '
--- snip ---
:~$ 

但不在我输入的文件中:

~$ cat /etc/profile.d/custom.sh
--- snip ---
alias fschk="df -h|grep -vE '^/dev/root|tmpfs'|awk '{print $5 " " $1}'"
--- snip ---
~$ 

似乎ash有一个不同/简化的版本,alias但我无法弄清楚这个版本。

任何指示将不胜感激。

提前致谢。

最好的,

聚己内酯

答案1

你的别名,

alias fschk="df -h|grep -vE '^/dev/root|tmpfs'|awk '{print $5 " " $1}'"

是一个双引号字符串。因此,当 shell 定义别名时,它会在字符串中展开$5和。$1为了避免这种情况,请确保避开美元符号。

别名还包含双引号,如果您不希望它们中断字符串,则需要对其进行转义。

alias fschk="df -h | grep -vE '^/dev/root|tmpfs' | awk '{ print \$5 \" \" \$1}'"

或者,简化一下:

alias fschk="df -h | awk '!/^\/dev/root|tmpfs/ { print \$5, \$1 }'"

或者,作为 shell 函数(在这种情况下,引用根本没有任何问题):

fschk () {
    df -h | awk '!/^\/dev/root|tmpfs/ { print $5, $1 }'
}

或者,作为一个接受文件系统列表的函数,以避免提取df以下信息:

fschk () {
    df -h | (
        IFS='|'
        pat="${*:+^($*)}" awk 'ENVIRON["pat"] == "" || $0 !~ ENVIRON["pat"] { print $5, $1 }'
    )
}

你会像这样使用它

fschk tmpfs /dev/root

事实上,我建议您将所有别名重写为 shell 函数。别名只对琐碎的事情有用。

相关内容