Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bash shell #40

Open
magicdawn opened this issue Sep 11, 2015 · 20 comments
Open

bash shell #40

magicdawn opened this issue Sep 11, 2015 · 20 comments
Labels

Comments

@magicdawn
Copy link
Owner

Things about bash shell.

And GNU Make see #26

resources

@magicdawn
Copy link
Owner Author

基本语法

注意空格, =两侧不要写空格, [ 条件 ] 方括号两侧写空格

name=hello

name+=' world' # hello world

count=1
count+=1 # 11 字符串拼接

count=1
let "$var+=1" # 2 此时是数学运算

((count++)) # 数学运算

if控制流

条件判断里, 用 [ 条件 ] 判断, [ ]test 相同 如:

  • [ -f "someFile"] someFile这个文件存在
  • [ -n $var ] var这个变量里面有值, 则为true
  • [ $a=$b ] a和b相等
  • [ -z string ] string长度为0

http://tldp.org/LDP/abs/html/tests.html

if ....; then
    expr
elif ...; then
    expr
else
    expr
fi

与and 或or

与或要分两种场景

  1. 在一个测试表达式中的与或
  2. 在一个if判断中的与或
  3. 在一个测试表达式中
    与用 -a, 或用 -o 表示
test -f some_file -a -d some_dir

# 等同于
[ -f some_file -a -d some_dir ]

# 在一个测试表达式中使用 `-a` 表示与, 同时满足

2.在一个 if 判断中
可以使用 && || 连接多个测试表达式

if [ -f some_file ] && [ -d some_directory ]; then
  echo "Well"
fi

for

for var in A B C; do
    echo $var
done

while & until

while ...; do
    expr
done

select var in A B C ; do
    break;
done
$var = A | B | C

case var in
    case1)
       expr;;
    case2)
       expr;;
esac

@magicdawn
Copy link
Owner Author

特殊符号

echo *.jpg
会扩展通用符,找出所有的 jpg 文件

echo "*.jpg ${SHELL}"
不扩展 *, 但会插入 $SHELL的值

echo '.jpg ${SHELL}'
原样输出, 不对变量求值

@magicdawn
Copy link
Owner Author

命令行参数

./file.sh arg1 arg2

$1 # 第一个命令行参数 arg1
$@ # 所有参数, for var in $@ 可以循环取出
$* # 所有参数, 但是 for in $* , 只会执行一次, 值是全部的值

$@ & $* 的区别

运行 ./args.sh hello world

#!/usr/bin/env sh

split(){
  echo "-----------------"
}


for x in $@; do
  echo $x
done
split

for x in "$@"; do
  echo $x
done
split

for x in $*; do
  echo $x
done
split

for x in "$*"; do
  echo $x
done

结果

hello
world
-----------------
hello
world
-----------------
hello
world
-----------------
hello world

@magicdawn
Copy link
Owner Author

函数

上面用了一个简单的 split 函数,

split(){
    echo '-----'
}

# 使用 `split` 来调用
# 在函数内部, 使用 `$1` 来代表传过来的第一个参数

@magicdawn
Copy link
Owner Author

set -e
http://stackoverflow.com/questions/19622198/what-does-set-e-mean-in-a-bash-script

有程序的exit code > 0, 就立即退出

@magicdawn
Copy link
Owner Author

Unix 系

alias v.s function

mnpm(){
  npm \
    --registry=http://r.npm.sankuai.com \
    --cache=$HOME/.cache/mnpm \
    --disturl=https://npm.taobao.org/dist \
    --userconfig=$HOME/.mnpmrc \
    $@
}

@magicdawn
Copy link
Owner Author

export declare typeset

http://linux.die.net/man/1/zshbuiltins

  • declare 同 typeset
  • export 同 typeset -gx

查看全局变量

export -p

  • OSX: 打印 typeset -x xxx
  • CentOS: 打印 declare -x xxx

更多资料
http://codingstandards.iteye.com/blog/1150109

  • -x 是设置为环境变量
  • -f 设置函数变量
  • -i 设置int变量

@magicdawn
Copy link
Owner Author

Shell 脚本学习指南

@magicdawn
Copy link
Owner Author

入门

2.5.5.1 重定向与管道

  • < 改变标准输入
  • > 改变标准输出
  • >> 附加到文件
  • | 建立管道, program1 | program2 可将1的标准输出作为2的标准输入

Note: Unix 新手可以将 < & > 想象成数据的漏斗, 从大的一端流向小的一端

2.5.5.2

两个特殊文件

  • /dev/null
    位桶(bit bucket), 传送到此文件的数据都会被系统丢掉
    可以将输出丢掉而得到命令的 exit code
if grep pattern myfile > /dev/null; then
  echo "found."
else
  echo "Go Away"
fi
  • /dev/tty

当程序打开此文件时, UNIX 会自动将它重定向到一个终端, 再与程序结合. 一个终端(实体控制台 or 串行端口 or 通过网络与窗口登录的伪终端)

看不懂...

2.5.6 PATH环境变量

在用户的角度来看, PATH中的可执行文件和shell脚本并无不同

PATH环境变量中的空白, 同 . 一样, 表示当前目录, 如

# 第一个是 `:` 于是第一部分就是空白
PATH=:/usr/bin/:/usr/local/bin

# 中间有空白, `::`
PATH=/usr/bin::/usr/local/bin

建议使用 .

2.6 argv

命令行参数

$1 # 第1个命令行参数

$9 # 第9个

${10} # 第10个

@magicdawn
Copy link
Owner Author

3 查找与替换

grep

grep = g/ re /p = 全局性匹配 re ,并将其打印

usage: grep [-flag] pattern

flags explaination example
-F 使用普通的字符串匹配, 默认传字符串即是此 flag grep -F magicdawn
-E 使用 Extended Regular Expressions匹配(pattern需要引号) grep -E "^magic"
-f 指定输入文件 grep -f awesome_file.txt hello
-l 列出匹配到的字符所在的文件名 grep -l -f *.txt hello
-v 显示不匹配的行, 相当于反选 grep -v hello
-i 不区分大小写 ...
-q 不进行输出 ...

3.2 grep -E 支持的正则

规则与JavaScript RegExp不一致的部分:

  1. POSIX reg支持字符集

    # [:alnum:] 数字字符
    grep -E "[[:alnum]]{3,}"

    等等, 这种反而不好记
    image

  2. 后向引用
    \1 去重复第一个分组

    $ echo "abeeeba" | grep -E "(a)(b)[cde]*\2\1"
    abeeeba
  3. \< \> 等同于 \b, 单词边界


3.2.6 sed

# 将 `magicdawn` replace 为 tao
$ who | sed "s/magicdawn/tao/"

image

sed "s/magicdawn/tao/g"

  • g表示全局替换, sed划分范围是行, 上面没有设置 g, 但是每行都替换了
  • 下面一行出现两次 magicdawn, 结果只有第一个被替换
$ echo "magicdawn and magicdawn" | sed "s/magic/tao/"
taodawn and magicdawn

s/ , s后的第一个字符作为分隔符.

@magicdawn
Copy link
Owner Author

6

env

set environment and execute command, or print environment

  • -i 去除继承的全局变量

    $ env -i node
    env: node: No such file or directory
    
    # 此时 PATH 环境变量也被去掉
    # 使用如下命令去设置 PATH
    $ env -i PATH=$PATH node
    > process.env
    { PATH: '...',
      __CF_USER_TEXT_ENCODING: '0x1F5:0:0' }
    >
  • #!/usr/bin/env node

unset

从执行的shell中删除变量 & 函数

# 删除变量, 默认 -v
unset -v var_name
unset var_name

# 删除函数
unset -f fn_name

6.1.2 参数展开

syntax explanation
$var or ${var} simplest

特殊变量
http://tldp.org/LDP/abs/html/refcards.html#AEN22402

syntax explanation example
$0 被执行的脚本名 sh ch6/args.sh => ch6/args.sh
$1 - $9 argv ...
${10} argv, 超过9, 要使用 {} 包起来 ...
$# argv.length 提供给脚本执行的参数的个数 ...
$* & $@ 所有的命令行参数 echo $@
sh args.sh -a --b => -a --b
"$@" 作为 separate words 在shell script作为中间人, 传送参数时采用
"$*" 作为 single word ...
$? 前一条命令的 exit status ...

6.2.1 Exit Status

status explanation
0 成功
1-125 在重定向 or 单词展开期间失败
126 命令找到了,但文件无法执行
127 找不到命令
> 128 程序收到 singal 而死亡

6.5 函数

fn_name(){
  # $0 - $9 变成了形参
  # return 同 exit
}

# 调用函数并存储结果
x=$(fn_name 参数)

@magicdawn
Copy link
Owner Author

7

重定向

0,1,2 分布代表 stdin, stdout, stderr

# 将stdout输出至out.log, 将stderr输出至err.log
program 1> out.log 2> err.log

# 将stderr重定向至stdout
# `2>&1` 要在 `>out.log` 之后
# shell处理重定向时, 从左至右, 2>&1时发现 `&1` 
#   是console, 则输出console
#   是out.log, 则输出是out.log
program >out.log 2>&1

7.5 通配符

syntax explanation
? 任何单一字符
* 任意字符串
[set] 任何在set里的字符
[!set] 任何不在set里的字符

dirname & basename

同 node.js 里 path.dirname & path.basename

$ basename ch2/dev-tty.sh
dev-tty.sh

$ basename ch2/dev-tty.sh ".sh"
dev-tty

$ basename ch2/dev-tty.sh sh
dev-tty.

@magicdawn
Copy link
Owner Author

date

$(date +"%Y-%m-%d %H:%M:%S")

@magicdawn
Copy link
Owner Author

@magicdawn
Copy link
Owner Author

magicdawn commented Aug 11, 2016

ps

OSX

flag explaination
-a 显示其他用户 & 自己的进程, 如果没有指定 -x , 那么会跳过没有 controlling terminal 的进程
-x 包含没有 controlling terminal 的进程
-A / -e = -ax
-O 往输出里添加信息, 例如 -O "%cpu" 添加cpu 占用率
-o 只输出指定的信息, 例如 -o "pid, command" 只输出 pid & command 列

Linux

@magicdawn
Copy link
Owner Author

magicdawn commented Aug 11, 2016

xargs

http://man.linuxde.net/xargs

xargs [options] [command]

command 默认是 echo

options

  • -n 几项换行, 默认不换行, 使用 echo /bin/*.sh | xargs -n x 尝试

  • -I $ 指定 $ 为循环变量, 在后续命令中可以使用

    # 例如
    ls -1 projects/iya/*.* | xargs -I $ cp $ /tmp/test/

@magicdawn
Copy link
Owner Author

magicdawn commented Aug 11, 2016

rsync

http://man.linuxde.net/rsync

@magicdawn
Copy link
Owner Author

crontab

http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/crontab.html

第一列 第二列 第三列 第四列 第五列
分钟 小时 分 月 星期(0&7 = 周天)

@magicdawn
Copy link
Owner Author

magicdawn commented Nov 2, 2018

ln

http://man.linuxde.net/ln

ln -s src target

src: 已经存在的文件, 箭头右边
target: 要创建的 symlink 名字, 可以省略

shell script path

# ------------- SCRIPT ------------- #

#!/bin/bash

echo
echo "# arguments called with ---->  ${@}     "
echo "# \$1 ---------------------->  $1       "
echo "# \$2 ---------------------->  $2       "
echo "# path to me --------------->  ${0}     "
echo "# parent path -------------->  ${0%/*}  "
echo "# my name ------------------>  ${0##*/} "
echo
exit

# ------------- CALLED ------------- #

# Notice on the next line, the first argument is called within double, 
# and single quotes, since it contains two words

$  /misc/shell_scripts/check_root/show_parms.sh "'hello there'" "'william'"

# ------------- RESULTS ------------- #

# arguments called with --->  'hello there' 'william'
# $1 ---------------------->  'hello there'
# $2 ---------------------->  'william'
# path to me -------------->  /misc/shell_scripts/check_root/show_parms.sh
# parent path ------------->  /misc/shell_scripts/check_root
# my name ----------------->  show_parms.sh

# ------------- END ------------- #

@magicdawn
Copy link
Owner Author

magicdawn commented Apr 3, 2023

flag list

args=( 
  --app-icon '/Applications/Platypus.app/Contents/Resources/PlatypusAppIcon.icns'
  --interface-type 'Text Window' --text-font 'Jetbrains Mono 16'
  --author 'magicdawn'
  --interpreter '/bin/zsh'
  --optimize-nib
  --overwrite
)

platypus "${args[@]}" \
  --quit-after-execution \
  --name "<name here>" \
  --interpreter-args $'-c|set -x; <cmd here>' \
  "$(dirname "$0")/default.sh" "$HOME/Applications/Platypus/<app name here>.app"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant