# Linux 重定向交流脚本

> 前天在床上玩手机的我，刷到这样一条视频 [(服务器搭建SSH聊天室，老掉牙的聊天室)](https://www.bilibili.com/video/BV1qe4y1S7ch?share_source=copy_web&vd_source=f00ac04b6b3e3278b6528d4af2ad31d7) ，通过命名文件夹和修改文本文件来实现超古老的信息传递方法，由此我的兴趣突发，我想到能不能通过脚本，把复杂的操作过程简化并优化。
>
> 后来我查询资料的时候，发现了通过重定向符号 ">" 可以将输出结果重定向到其他在线的终端，于是就弄出了下面这个脚本工具，其实 Linux 就已经自带了一个简单的信息交流工具了，比如：write和wall，但实在是闲不住，就……

[TOC]

## 一开始的想法

使用 Shell 脚本和参数传递，通过更改命令参数，实现选择功能，功能一就是每隔 5 秒执行 1 次 `cat [file]` 以达到实时输出信息效果，功能二就是发送信息，而功能三就是全局信息。

但这只是想了，后来发现有其他方法就替换了这个。

## 实现的功能

通过传递参数选择功能，但不需要创建和修改文件了，通过重定向符号，把 `echo` 输出结果重定向到另一个终端，这样就直接实现了发送和实时显示功能了。

然后通过 `who` 列出在线用户和对应的终端号，这样，就简单实现了我要的功能了。

但这个有个缺点就是不能多人信息交流，只能发给对应的用户，而全局信息还是一样的。

> 其实，写完后我发现，我所做的只是把 Linux 自带的命令整合起来，方便使用

最终，就弄出了这么一个脚本工具了。

## Shell 脚本源码

`~/chat.sh`

```shell
version="v1.1 Beta"

# 分隔符宏定义
hr="-"

# 当前时间
time="\033[0;35m"`date "+%Y-%m-%d %H:%M:%S"`"\033[0m"
# 发送者信息
sender="\033[0;32m"`who am i | awk '{print $1"("$2")"}'`"▶\033[0m"

# 无参数和帮助信息输出
if [[ -z "$1" || "$1" = "-h" ]]; then
    printf "Usage: chat [arg]\nArg:\n"
    printf "  %-4s%s\t%s\n" "-h," "-help" "Get command help."
    printf "  %-4s%s\t%s\n" "-a," "-about" "About the script tool."
    printf "  %-4s%s\t%s\n" "-l," "-list" "List online users."
    printf "  %-4s%s\t%s\n" "-t," "-to" "Who do you want to send it to?"
    printf "  %-4s%s\t%s\n" "-s," "-send" "What do you want to text him/her?"
    printf "\nExample:\n"
    printf "  %-4s\t%s\n" "\"chat -a -l\"" "Show about info and list online users."
    printf "  %-4s\t%s\n" "\"chat -t -s\"" "Send message to him/her."
    printf "  %-4s\t%s\n" "\"chat -t [pts num] -s\"" "Enter the user to send in advance."
    printf "  %-4s\t%s\n" "\"chat -t [pts num] -s [text]\"" "Send a message with one click."
    printf "\nDon't use this two pairs of parameter at the same time:\n"
    printf "  \"-a -l\" and \"-t -s\"\n\n"
fi

# 参数判断处理
for i in "$@"
do
    case $i in
        -a|-about)
            printf "\n SSH 信息交流脚本\n"
            printf "%32s\n" | tr " " $hr
            printf " 版本：$version\n 作者：龙介LongJie\n 网站：https://longjie233.top\n\n   在同一个服务器，不同的地理世\n 界中，如何做到信息的交流呢？\n   当然是最古老的创建文本写上内\n 容了。\n   这个脚本是通过重定向符号，把\n 信息传递给另一个终端里。\n\n"
        ;;
        -l|-list)
            str=`who | awk '{print "用户：" $1 " 终端：" $2}'`
            str_len=`who | awk '{print "用户：" $1 " 终端：" $2}' | wc -L`

            printf "\n%-`expr $str_len + 6`s\n" " 在线用户"
            printf "%`expr $str_len + 3`s\n" | tr " " $hr
            printf " %s\t%s\n" $str
            printf "\n"
        ;;
        -t|-to)
            continue
        ;;
        -s|-send)
            if [[ "$3" = "-s" || "$3" = "-send" ]]; then
                if [ -n "$4" ]; then
                    printf "\n\n${time}\n${sender} $4\n" > /dev/pts/$2
                else
                    read -r -e -p "Send message (str): " msg&&printf "\n\n${time}\n${sender} ${msg}\n" > /dev/pts/$2
                fi
            elif [[ "$2" = "-s" || "$2" = "-send" ]]; then
                read -p "Send to (int): " to
                read -r -e -p "Send message (str): " msg&&printf "\n\n${time}\n${sender} ${msg}\n" > /dev/pts/$to
            else
                echo "Sent to who?"
            fi
        ;;
    esac
done
```

## “食用”文档

| 参数       | 说明                    |
| ---------- | ----------------------- |
| -h, -help  | 获取命名帮助信息        |
| -a, -about | 关于这个脚本工具的信息  |
| -l, -list  | 列出在线用户            |
| -t, -to    | 你要发送给哪个人？      |
| -s, -send  | 你要发送啥信息给他/她？ |

### 使用例子：

同时显示关于信息和在线用户

```bash
chat.sh -a -l
```

发送消息给 0 号终端

```bash
chat.sh -t 0 -s
```

发送消息给 0 号终端并预先输入好内容

```bash
chat.sh -t 0 -s "hello, world"
```



**注意！**不要把 `-a -l` 和 `-t -s` 同时使用，因为我没弄参数判断，不然会出错的。

## 为脚本创建全局命令

Linux `alias` 设置别名，为长命令、脚本和可执行文件创建别名，方便自己用。使用 `alias` 创建名为 `chat` 的命令，并指向这个脚本。

编辑 `/etc/bashrc` 在最后一行增加一条命令

```shell
alias chat="/usr/local/bin/chat.sh"
```

这里的 `/usr/local/bin/` 是我脚本文件的存放目录，可自定义。

然后，执行 `source /etc/bashrc` 使刚才的配置生效，最后就可以在任何地方使用该脚本了！