> For the complete documentation index, see [llms.txt](https://nuoxu2016.gitbook.io/shell/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://nuoxu2016.gitbook.io/shell/master.md).

# Shell cmd for Linux

## ls类

```bash
ls | wc -w  # 查看一个文件夹下有多少文件

# 查看一个文件夹下的各个文件的信息（包括权限和文件大小等）
ls -lh
```

## 创建快捷方式

```bash
ln -s /home/fff/Programs/ZendStudio/ZendStudio /home/fff/桌面
 
即在桌面创建Zend Studio的链接
```

加参数-s是创建软链接，相当于Windows下的快捷方式，不加-s是硬链接，就是会复制一个副本到目标位置，但是与复制不同，两个文件，只要修改一个，另一个会跟着改变。

## cp类

```bash
scp -r file1_path xunuo@100.100.22.3:file_path
# 把本地的文件上传到指定ip的服务器文件夹下

# 同时拷贝多个文件
cp /home/usr/dir/file{1..4}.txt ./
```

## nohup后台运行

在后台运行程序，且把程序的输出存在nohup.out中。**python -u** 启动python文件的作用是不缓存，直接把输出重新定向到文件

```bash
nohup python -u script.py &
```

```bash
nohup python -u test.py > test.out 2>&1 &
```

&#x20;**> test.out** 表示，把**stdout** 输出到 **test.out**这个文件里。默认情况下，是输出到 **nohup.out**

**2 > &1** 表示： 把 **stderr** 也输出到 **stdout**中

## 进程类指令

```bash
killall -u xunuo # 杀掉 xunuo这个用户所启动的所有的PID

ps -uq PID       # 查询某个进程是由谁启动起来的

lsof   -i:6666   #查看占用端口6666的所有进程

ls - # 查看python启用的所有进程与指令

```

## 服务器远程指令

### 端口转发

**反向端口**转发是把本机的端口转发到远程的机子上；与之对应，**正向端口**转发则是把远程的端口转发到本地。

如果在家，想连接实验室或者学校的局域网，j将远端服务器的某个端口映射到本地，从而实现远程debug.或者使用远程的解释器进行编译，那么需要如何操作呢？

这个时候，我们需要一台处在公网的机器。假设现在有一台出于公网，有公网ip的跳板机jumpbox

那么，想远程访问，可使用以下指令。当然完成该指令的前提是远端的服务器添加了本机的ssh public\_key。

```bash
ssh -p 1111 xunuo@dl1.datagrand.net -fN -L 45455:100.100.22.4:45455

# -N 表示 非不执行命令，只做端口转发
# -f 表示 在后台运行
# -L 表示 正向转发
```

```bash
# 1. 首先，在服务器的终端下运行
python -m http.server 8001
# 运行后，会在服务器下产生一个loaclhost:8001的服务

# 2. 在本地，通过ssh，将100.100.22.2的地址映射到本地8000端口
ssh xunuo@100.100.22.2 -N -L localhost:8000:localhost:8000

# 3. 此时，就可以在浏览器http://localhost:8000查看远端的文件
```

## 权限类指令

```bash
chmod 777 folder_name # 开放文件夹的所有权限

# 从指定源下载某python包
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple XXX
 
```

## sed

```bash
sed -i "s/\(dockerhub.com\/\)\(.*\)\(\/$DOCKER_IMAGE:release_\)
\(.*\)/\1ysocr\3$DOCKER_TAG_SUFFIX/g" docker-compose.yml
```

s/ 是字符的头部 /g 是在特定字符组的尾部进行添加的意思

`\(dockerhub.com\/)` 是第一组。一组字符是用括号括起来表示的，其中 \ 代表转义符

&#x20;`\(.*)\` 第二组&#x20;

`(\/$DOCKER_IMAGE:release_\)`第三组

\1ysor 是在第一组字符后面添加 ysor 这个字符，于是就变成了 `dockerhub.com/ysocr`

## 其他

`>&` is the syntax to redirect a stream to another file descriptor - 0 is stdin, 1 is stdout, and 2 is stderr.

因此，you can redirect stdout to stderror by doing

```bash
echo test 1>&2
> 的真实作用是redirection


ls -ld /tmp /tnt 2>/dev/null
/tmp 不存在的时候， 输出为：

drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp
```

/dev/null is a special filesystem object that throws away everything written into it. Redirecting a stream into it means hiding an output.

```bash
$(docker ps -q ${test_container_name} 2> /dev/null)
这个是只把docker ps -q 跑出来的stderr 送到/dev/null这个坟场进行销户
 cannot access file_doesnot_exists: No such file or directory 就算是一个 stderr
```

## 检查两个文件夹之前缺失的文件

开发中，时常遇到这么一个问题：图片文件夹中有1000张图，但是对应的label却只有999张。那么，究竟是哪一个图的label被我漏掉了呢？

这里的思路是把所有文件的文件名存为一个txt文件，然后用vimdiff进行查找

```bash
ls -lt pic|grep -v total|awk '{print $9}'|awk -F. '{print $1}'|sort > pic.txt
ls -lt label|grep -v total|awk '{print $9}'|awk -F. '{print $1}'|sort > label.txt
vimdiff pic.txt label.txt
```

## curl

```bash
curl http://ysocr.datagrand.cn/ysocr/ocr -F "file=@/Users/nuoxu/Desktop/test_10.jpeg" -H "token: 222" -v
```

将本地上传到某个请求服务，

&#x20;**-- F**

This lets **curl** emulate a filled-in form in which a user has pressed the submit button. This causes **curl** to **POST** data using the Content-Type **multipart/form-data** according to RFC1867. This enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an "**@**" character.

## find

```bash
# find all files whose name is test.txt in a current directory
find . -name test.txt

# find files using name and ignoring case
find /home -iname test.txt 

# find php files using name
find . -type f -name tecmint.php

# find all php files in directory
find . -type f -name "*.php"

# find and remove multiple file
find . -type f -name "*txt" -exec rm -f {} \

# find file according to a certain condition
find . -type f -print | xargs grep "example"

# find empty file
find . -type f -empty

# find empty directory
find . -type d -empty
```

自动寻找空闲的GPU

```python
def get_gpu_memory_free_map():
    """Get the current gpu usage.

    Returns
    -------
    usage: dict
        Keys are device ids as integers.
        Values are memory usage as integers in MB.
    """
    result = subprocess.check_output(['nvidia-smi', '--query-gpu=memory.free', '--format=csv,nounits,noheader'],
                                     encoding='utf-8')
    # Convert lines into a dictionary
    gpu_memory_free = [int(x) for x in result.strip().split('\n')]
    gpu_memory_free_map = dict(zip(range(len(gpu_memory_free)), gpu_memory_free))
    return gpu_memory_free_map


if "CUDA_VISIBLE_DEVICES" in os.environ:
    if os.environ["CUDA_VISIBLE_DEVICES"] == "auto":
        # 此时必须在外部制定环境变量MEMORY_USAGE
        MEMORY_USAGE = int(os.environ["MEMORY_USAGE"])
        memory_free_map = get_gpu_memory_free_map()
        for i in memory_free_map:
            if memory_free_map[i] >= MEMORY_USAGE:
                os.environ["CUDA_VISIBLE_DEVICES"] = str(i)
                break
        if os.environ["CUDA_VISIBLE_DEVICES"] == "auto":
            print("GPU MEMORY NOT ENOUGH")
            sys.exit(0)
else:
    os.environ['CUDA_VISIBLE_DEVICES'] = "-1"
 
```

**cat /proc/meminfo**\
查看RAM使用情况最简单的方法是通过命令：cat /proc/meminfo

**cat /proc/cpuinfo**

查看CPU详情和依赖的指令集

**vmstat -s**\
vmstat命令显示实时的和平均的统计，覆盖CPU、内存、I/O等内容。例如内存情况，不仅显示物理内存，也统计虚拟内存

## 快捷键

```bash
Ctrl + a  移动到命令行首
Ctrl + e  移动到命令行尾
```

## 脚本实现列举所有文件夹下文件

在训练模型的时候，总有需要把某个文件夹的所有文件名罗列在同一个txt文件下的需求，以前总是用Python来实现，但是实际上几行shell脚本就可以搞定

```bash
ls ./datasets/train/img/*.jpg > ./datasets/train_img.txt
ls ./datasets/train/gt/*.txt > ./datasets/train_gt.txt
paste ./datasets/train_img.txt ./datasets/train_gt.txt > ./datasets/train.txt
```

## 查看目录下面的文件大小

```bash
du -h -d 1  # Recursive 操作，查看各个目录的大小

du -h --max-depth=1 zhoubingcheng/ # 查看某特定文件夹下各个文件的大小

df -h  # 查看当前目录下每个文件夹的大小
```

## 通过跳板机，从某个服务器下载文件

当我们需要通过跳板机去登录某个服务器的时候，比如

```bash
ssh -t -p 12345 xunuo@jumper-huabei2-vpc.xunuo.com ssh duser@172.0.0.123
```

并希望从123这台机器上下载某些文件到本地的时候，可以用以下指令

```bash
rsync -e "ssh -t -p 12345 xunuo@jumper-huabei2-vpc.xunuo.com ssh" -avz duser@172.0.0.123:/data/duser/data/ /Users/nuoxu/Desktop/
```
