概述
文章目录
- @[TOC](文章目录)
- 知识点总结
- shell tools
- 课后练习
文章目录
- @[TOC](文章目录)
- 知识点总结
- shell tools
- 课后练习
知识点总结
- Assign variables
missing % foo=bar
missing % $foo
zsh: command not found: bar
missing % echo $foo
bar
missing % foo = bar
zsh: command not found: foo
- The difference between “” and ‘’
Strings delimited with ’ are literal strings and will not substitute variable values whereas " delimited strings will.
missing % echo "$foo"
bar
missing % echo '$foo'
$foo
- As with most programming languages, bash supports control flow techniques including if, case, while and for.
missing % cat mcd
mcd (){
mkdir -p "$1"
cd "$1"
}
missing % mcd test
zsh: command not found: mcd
missing % source mcd
missing % mcd test
常用的参数
- $0 - Name of the script
- $1 to $9 - Arguments to the script. $1 is the first argument and so on.
- $@ - All the arguments
- $# - Number of arguments
- $? - Return code of the previous command
- ’$$‘ - Process identification number (PID) for the current script
- !! - Entire last command, including arguments. A common pattern is to execute a command only for it to fail due to missing permissions; you can quickly re-execute the command with sudo by doing sudo !!
- $_ - Last argument from the last command. If you are in an interactive shell, you can also quickly get this value by typing Esc followed by . or Alt+.
- Return code
shell 里面的return code和后面的逻辑连接符,不能用我们之前的思维方式来理解。
|| - 可以理解为异常处理,如果前面异常,那就执行后面的内容
&& - 可以理解为继续执行,如果前面正常,那就继续执行后面的内容
missing % false || echo "Oops, fail"
Oops, fail
missing % true || echo "Will not be printed"
missing % false && echo "Will not be printed"
missing % true && echo "Things went well"
Things went well
missing % true ; echo "This will always run"
This will always run
missing % false; echo "This will always run"
This will always run
- Get the output of a command as a variable
#!/bin/bash
echo "Starting program at $(date)"
echo "Running program $0 with $# arguments with pid $$"
for file in "$@"; do
grep foobar "$file" > /Users/missing-semester/missing/output
if [[ $? -ne 0 ]]; then
echo "File $file does not have any foobar, adding one"
echo "# foobar" >> "$file"
fi
done
missing % ./lec2 semester mcd
Starting program at Mon Apr 4 13:55:44 CST 2022
Running program ./lec2 with 2 arguments with pid 74734
File mcd does not have any foobar, adding one
missing % cat mcd
mcd (){
mkdir -p "$1"
cd "$1"
}
# foobar
missing %
注意事项
- 尽量使用[[]]而不是[],以避免不必要的错误。详细原因见http://mywiki.wooledge.org/BashFAQ/031
- 相似的参数,使用快捷命令
- 通配符
?和*
rm foo?
rm foo*
- {}
missing % mkdir foo bar
missing % touch {foo,bar}/{a..h}
missing % touch foo/x bar/y
missing % diff <(ls foo) <(ls bar)
9c9
< x
---
> y
missing % tree
.
├── bar
│
├── a
│
├── b
│
├── c
│
├── d
│
├── e
│
├── f
│
├── g
│
├── h
│
└── y
├── foo
│
├── a
│
├── b
│
├── c
│
├── d
│
├── e
│
├── f
│
├── g
│
├── h
│
└── x
├── lec2
├── mcd
├── output
└── semester
2 directories, 22 files
- change shell excute env
#!/usr/local/bin/python
import sys
for arg in reversed(sys.argv[1:]):
print(arg)
- Shell function 和script 的区别
- shell里的functions需要用同一种语言。比如一开始声明的“#!/usr/local/bin/python”。而script可以用任意语言去写。
- functions在它们的定义被读到的时候就加载了。而脚本是每次执行的时候都会被加载一次。所以相对来说,functions加载速度会稍微快一点,但是每次修改它们之后它们又需要重新加载一下它们的定义。
- functions是在它们当前所在的shell环境中执行的,而script运行在它们自己的进程里。因此,function可以改变环境变量,比如改变你当前的文件目录,但是script不可以。script需要用export来传递环境变量参数
shell tools
- finding how to use commands
- -h or --help
- man
- finding files
- find
# Find all directories named src
find . -name src -type d
# Find all python files that have a folder named test in their path
find . -path '*/test/*.py' -type f
# Find all files modified in the last day
find . -mtime -1
# Find all zip files with size in range 500k to 10M
find . -size +500k -size -10M -name '*.tar.gz'
# Delete all files with .tmp extension
find . -name '*.tmp' -exec rm {} ;
# Find all PNG files and convert them to JPG
find . -name '*.png' -exec convert {} {}.jpg ;
- locate
- finding code
- grep
- finding shell commands
- history / ctrl + R
- history-based autosuggestions
fish
missing ~ % fish
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
missing ~> help
missing ~> cd Documents/C_Programming/missing-semester/
# 自动补全
- directory navigation
fasd autojump // ranks files and directories by frequency and recency
tree
broot
nnn
ranger
课后练习
- Read man ls and write an ls command that lists files in the following manner
- Includes all files, including hidden files // -a
- Sizes are listed in human readable format (e.g. 454M instead of 454279954) // -h
- Files are ordered by recency // -t
- Output is colorized // -G
- A sample output would look like this
-rw-r--r-- 1 user group 1.1M Jan 14 09:53 baz
drwxr-xr-x 5 user group 160 Jan 14 09:53 .
-rw-r--r-- 1 user group 514 Jan 14 06:42 bar
-rw-r--r-- 1 user group 106M Jan 13 12:12 foo
drwx------+ 47 user group 1.5K Jan 12 18:08 ..
my answer
missing ~> ls -lhGta
- Write bash functions marco and polo that do the following. Whenever you execute marco the current working directory should be saved in some manner, then when you execute polo, no matter what directory you are in, polo should cd you back to the directory where you executed marco. For ease of debugging you can write the code in a file marco.sh and (re)load the definitions to your shell by executing source marco.sh.
my answer
#!/bin/bash
# save current working directory to txt file
marco_path=$(pwd)
# 这里要特别注意 $(pwd)才是正确的写法啊!!!!!
# 或者使用 $PWD
marco () {
echo $marco_path > output.txt
}
polo () {
cd "$marco_path"
}
- Say you have a command that fails rarely. In order to debug it you need to capture its output but it can be time consuming to get a failure run. Write a bash script that runs the following script until it fails and captures its standard output and error streams to files and prints everything at the end. Bonus points if you can also report how many runs it took for the script to fail.
#!/usr/bin/env bash
n=$(( RANDOM % 100 ))
if [[ n -eq 42 ]]; then
echo "Something went wrong"
>&2 echo "The error was using magic numbers"
# 这里&2表示2输出通道
# 如果我把打印都输入到output.txt文件中 这条打印会打印在界面上 而不会保存在文件里
exit 1
fi
echo "Everything went according to plan"
my answer
#!/bin/bash
echo "The script is excuted at $(date)" >> output.txt
loop_cnt=0
flag=0
for ((loop_cnt=0; flag==0; loop_cnt++))
do
sh ex3.sh >> output.txt
if [[ $? -eq 1 ]]; then
let flag=1
fi
done
echo "It took $loop_cnt runs for the script to fail" >> output.txt
这里有疑问,我在脚本里写
$? || let flag=1
却不能执行,有待搞清楚
4. As we covered in the lecture find’s -exec can be very powerful for performing operations over the files we are searching for. However, what if we want to do something with all the files, like creating a zip file? As you have seen so far commands will take input from both arguments and STDIN. When piping commands, we are connecting STDOUT to STDIN, but some commands like tar take inputs from arguments. To bridge this disconnect there’s the xargs command which will execute a command using STDIN as arguments. For example ls | xargs rm will delete the files in the current directory.
Your task is to write a command that recursively finds all HTML files in the folder and makes a zip with them. Note that your command should work even if the files have spaces (hint: check -d flag for xargs).
If you’re on macOS, note that the default BSD find is different from the one included in GNU coreutils. You can use -print0 on find and the -0 flag on xargs. As a macOS user, you should be aware that command-line utilities shipped with macOS may differ from the GNU counterparts; you can install the GNU versions if you like by using brew.
my answer
5. (Advanced) Write a command or script to recursively find the most recently modified file in a directory. More generally, can you list all files by recency?
my answer
最后
以上就是儒雅水池为你收集整理的Lecture 2 - Shell Tools and Scripting的全部内容,希望文章能够帮你解决Lecture 2 - Shell Tools and Scripting所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复