BNU-FZH

fengzhenhua@outlook.com

添加方式 语法 多元素 下标连续 下标改变 覆盖原元素
直接下标添加 array_name[index]=value
数组长度添加 array_name[${#array_name[@]}]=value
数组长度添加 array_name[${#array_name[*]}]=value
重新创建数组 array_name=("${array_name[@]}" value1 ... valueN)
赋值运算符+= array_name+=(value1 ... valueN)

综上可知,是最通用的方案。

当编写脚本时,可能会遇到需要的命令在系统中没有安装, 此时需要解决命令依赖的问题,解决方法为安装对应的软件。Linux下大量的发行版,且不同发行版一般使用不同的包管理器,这导致了安装软件需要执行不同的安装命令,于是需要解决第二个问题:使用通用Linux命令探测系统安装的包管理器,然后确定安装命令。但是有时候,软件包提供的命令与其包的名称并不一致,这里就需要建立一个命令与包的映射关系,以正确执行安装命令。按照这个思路,本文提供一个基础的脚本:

通用安装脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#! /bin/sh
#
# readycmd.sh
# Author : fengzhenhua
# Email : fengzhenhua@outlook.com
# Date : 2024-06-14 15:58
# CopyRight: Copyright (C) 2022-2030 FengZhenhua(冯振华)
# License : Distributed under terms of the MIT license.
# Objective: 在不同的发行版中安装命令与软件包名不同的命令
#
# 包管理器列表: 管理器=安装命令
declare -A RD_PKG=(\
["pacman"]="pacman -S --needed --confirm" #arch endeavour manjaro 等
["apt-get"]="apt-get -y install" #debian ubuntu 等
["yum"]="yum -y install" #redhat centos7 及以下
["dnf"]="dnf -y install" #fedora centos8
["zypper"]="zypper -y install" #open suse
)
# 待安装软件列表: 命令=软件名
declare -A RD_CMD=(\
["unar"]="unarchiver" ["ssh"]="openssh" ["nvim"]="neovim"
)
# 选择发行版中的包管理器
for sh_pkg in ${!RD_PKG[*]}; do
which $sh_pkg &> /dev/null
if [ $? = 0 ]; then
RD_PKG_INS=${RD_PKG[$sh_pkg]}
fi
done
# 使用发行版中的包管理器安装系统中缺失的命令
for sh_cmd in ${!RD_CMD[*]}; do
which ${sh_cmd} &> /dev/null
if [ ! $? = 0 ]; then
sudo ${RD_PKG_INS} ${RD_CMD[$sh_cmd]}
fi
done

find , locate, whereis 和which 的区别

  • which:常用于查找可直接执行的命令。只能查找可执行文件,该命令基本只在$PATH路径中搜索,查找范围最小,查找速度快。默认只返回第一个匹配的文件路径,通过选项 -a 可以返回所有匹配结果。

  • whereis:不只可以查找命令,其他文件类型都可以(man中说只能查命令、源文件和man文件,实际测试可以查大多数文件)。在$PATH路径基础上增加了一些系统目录的查找,查找范围比which稍大,查找速度快。可以通过 -b 选项,限定只搜索二进制文件。

  • locate:超快速查找任意文件。它会从linux内置的索引数据库查找文件的路径,索引速度超快。刚刚新建的文件可能需要一定时间才能加入该索引数据库,可以通过执行updatedb命令来强制更新一次索引,这样确保不会遗漏文件。该命令通常会返回大量匹配项,可以使用 -r 选项通过正则表达式来精确匹配。

  • find:直接搜索整个文件目录,默认直接从根目录开始搜索,建议在以上命令都无法解决问题时才用它,功能最强大但速度超慢。除非你指定一个很小的搜索范围。通过 -name 选项指定要查找的文件名,支持通配符。

find , locate, whereis 和which 的用法

1. find

find是最常见和最强大的查找命令,你可以用它找到任何你想找的文件。

find的使用格式如下:

  $ find <指定目录> <指定条件> <指定动作>

  - <指定目录>: 所要搜索的目录及其所有子目录。默认为当前目录。

  - <指定条件>: 所要搜索的文件的特征。

  - <指定动作>: 对搜索结果进行特定的处理。

如果什么参数也不加,find默认搜索当前目录及其子目录,并且不过滤任何结果(也就是返回所有文件),将它们全都显示在屏幕上。

find的使用实例:

  $ find . -name "my*"

搜索当前目录(含子目录,以下同)中,所有文件名以my开头的文件。

  $ find . -name "my*" -ls

搜索当前目录中,所有文件名以my开头的文件,并显示它们的详细信息。

  $ find . -type f -mmin -10

搜索当前目录中,所有过去10分钟中更新过的普通文件。如果不加-type f参数,则搜索普通文件+特殊文件+目录。

2. locate

locate命令其实是“find -name”的另一种写法,但是要比后者快得多,原因在于它不搜索具体目录,而是搜索一个数据库(/var/lib/locatedb),这个数据库中含有本地所有文件信息。Linux系统自动创建这个数据库,并且每天自动更新一次,所以使用locate命令查不到最新变动过的文件。为了避免这种情况,可以在使用locate之前,先使用updatedb命令,手动更新数据库。

locate命令的使用实例:

  $ locate /etc/sh

搜索etc目录下所有以sh开头的文件。

  $ locate ~/m

搜索用户主目录下,所有以m开头的文件。

  $ locate -i ~/m

搜索用户主目录下,所有以m开头的文件,并且忽略大小写。

3. whereis

whereis命令只能用于程序名的搜索,而且只搜索二进制文件(参数-b)、man说明文件(参数-m)和源代码文件(参数-s)。如果省略参数,则返回所有信息。

whereis 命令的使用实例
1
2
$ whereis grep 
grep: /usr/bin/grep /usr/share/man/man1/grep.1.gz /usr/share/man/man1p/grep.1p.gz /usr/share/info/grep.info.gz

4. which

which命令的作用是,在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果。也就是说,使用which命令,就可以看到某个系统命令是否存在,以及执行的到底是哪一个位置的命令。

which 命令使用实例
1
2
$ which date
/usr/bin/date

python中存在一种叫做字典的数据类型,字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值 key:value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {},格式如下所示:

1
d = {key1 : value1, key2 : value2 }

关联数组的定义

shell中称为关联数组,可以使用任意的字符串、或者整数作为下标来访问数组元素。关联数组使用 declare 命令来声明,语法格式如下:

1
declare -A array_name

-A选项就是用于声明一个关联数组。关联数组的键是唯一的。以下实例我们创建一个关联数组 site,并创建不同的键值:

实例
1
declare -A site=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")

我们也可以先声明一个关联数组,然后再设置键和值:

实例
1
2
3
4
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"

关联数组的访问

访问关联数组元素可以使用指定的键,格式如下:

实例
1
2
3
4
5
6
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"

echo ${site["runoob"]}

执行脚本,输出结果为:

result
1
www.runoob.com

对于一些不确定的大量数组,我们可以直接使用默认的编号方式赋值或取出结果,然后可以用循环来处理每一条记录。但是对于某些数量有限,且有一些特意义的情况使用关联数组可以大大提高程序的可读性。例如,我们需要在系统中检测一下是否存在命令unar, 如果不存在则安装程序,但是程序的名称却是unarchiver, 因此可以定义一个关联数组解决:

实例
1
2
3
declare -A cmd
cmd["unar"]="unarchiver"
sudo pacman -S ${cmd["unar"]}

在不同的系统中存在不同的软件包管理器,此时可以通过定义关系数组来实现统一的管理脚本程序。

关联数组的特殊值

关联数组的特殊值
1
2
3
4
5
6
7
8
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"

echo ${#site[*]} #输出数组的元的个数(大小)
echo ${!site[*]} #输出全部的键名
echo ${site[*]} #输出全部的值

注意:上述echo中的*可以替换成@,效果等价。

前言:

EOFEnd Of File的缩写,表示自定义终止符。既然自定义,那么EOF就不是固定的,可以随意设置别名,意思是把内容当作标准输入传给程序,Linux中按Ctrl-d就代表EOF

Shell中我们通常将EOF<< 结合使用,表示后续的输入作为子命令或子Shell的输入,直到遇到EOF为止,再返回到主调Shell。回顾一下<<的用法,当Shell看到<<的时候,它就会知道下一个词是一个分界符。在该分界符以后的内容都被当作输入,直到Shell又看到该分界符(位于单独的一行)。这个分界符可以是你所定义的任何字符串。

用法:

1
2
3
<<EOF        //开始
....
EOF //结束

也可以自定义,如:

1
2
3
<<FFF        //开始
....
FFF //结束

注意:

第一个EOF必须以重定向字符<<开始,第二个EOF必须顶格写,否则会报错。如果将开始处的<<切换为<<-, 则结束分界符EOF前有制表符或者空格,则EOF此时仍然被当做结束分界符,此时EOF不必顶格写。

EOF配合cat能够进行多行文本输出。

通过cat配合重定向能够生成文件并追加操作,在它之前先回顾几个特殊符号:

1
2
3
4
<   :输入重定向
> :输出重定向
>> :输出重定向,进行追加,不会覆盖之前内容
<< :标准输入来自命令行的一对分隔号的中间内容

例:

1
2
3
4
5
6
7
[root@localhost ~]# cat <<EOF   //运行后会出现输入提示符">"
> Hello
> wolrd
> EOF
输入结束后,在终端显示以下内容:
Hello
wolrd

1. 向文件file1.txt中输入内容

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# cat >file1.txt <<EOF
> aaa
> bbb
> ccc
> EOF

[root@localhost ~]# cat file1.txt
aaa
bbb
ccc

追加内容至file1.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@localhost ~]# cat >>file1.txt <<EOF
> 111
> 222
> 333
> EOF

[root@localhost ~]# cat file1.txt
aaa
bbb
ccc
111
222
333

覆盖file1.txt

1
2
3
4
5
6
[root@localhost ~]# cat >file1.txt <<EOF
> Hello wolrd
> EOF

[root@localhost ~]# cat file1.txt
Hello wolrd

2. 自定义EOF

1
2
3
4
5
6
7
8
[root@localhost ~]# cat >file1.txt <<FFF
> test
> hello
> FFF

[root@localhost ~]# cat file1.txt
test
hello

3. 编写一个脚本,生成mysql配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@localhost ~]# vim /root/test.sh
#!/bin/bash
cat >/root/EOF/my.cnf <<EOF
[client]
port=3306
socket=/usr/local/mysql/var/mysql.sock
basedir=/usr/local/msyql/
datadir=/data/mysql/data
pid-file=/data/mysql/data/mysql.pid
user=mysql
server-id=1
log_bin=mysql-bin
EOF

[root@localhost ~]# cat /root/EOF/my.cnf //查看生成的mysql配置文件
[client]
port=3306
socket=/usr/local/mysql/var/mysql.sock
basedir=/usr/local/msyql/
datadir=/data/mysql/data
pid-file=/data/mysql/data/mysql.pid
user=mysql
server-id=1
log_bin=mysql-bin

4. 编写脚本向mysql数据库建表、赋值并查询

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# vim eof.sh
#!/bin/bash
mysql -uroot -p123456 <<EOF
use test;
create table data(name varchar(15),age int,address varchar(25));
desc test.data;
insert into data values("tom",23,"china");
select * from data;
exit
EOF

4.1 运行脚本查看执行结果

1
2
3
4
5
6
7
8
9
[root@localhost ~]# bash eof.sh    //运行脚本,查看数据库中信息
mysql: [Warning] Using a password on the command line interface can be insecure.
Field Type Null Key Default Extra
name varchar(15) YES NULL
age int(11) YES NULL
address varchar(25) YES NULL

name age address
tom 23 china

4.2 在数据库中查看新增的数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[root@localhost ~]# mysql -uroot -p123456
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+

mysql> use test;

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| data |
+----------------+

mysql> desc test.data;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| name | varchar(15) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| address | varchar(25) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+

mysql> select * from data;
+------+------+---------+
| name | age | address |
+------+------+---------+
| tom | 23 | china |
+------+------+---------+

5. EOF中的变量处理

在使用cat EOF中出现$变量通常会直接被执行,显示执行的结果。若想保持$变量不变需要使用 \ 符进行注释 . 当存在$变量过多,或存在赋值命令的时候可直接在EOF上加上双引号就行。

EOF处理变量
1
2
3
4
5
6
7
8
9
10
11
cat << "EOF" > ~/.gitconfig
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh
source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
source /usr/share/zsh-theme-powerlevel10k/powerlevel10k.zsh-theme
EOF

简介

ping (Packet Internet Groper)是一种因特网包探索器,用于测试网络连接量的程序。Ping是工作在 TCP/IP网络体系结构中应用层的一个服务命令, 但是缺点很明显,不够直观。可使用gping继续替代。gping是一个跨平台的命令行程序,当您尝试ping主机或网站时,该程序会在终端内部显示漂亮的图形。

github地址

https://github.com/orf/gping

安装方式

install gping
1
sudo pacman -S gping

使用方式

1
2
gping --help #查看帮助文档
gping -V #查看版本信息

实际运用

1
gping www.google.com
gping

取代ping

~/.zshrc
1
alias ping="gping"

这个简单的 ls 命令列出目录的内容十分方便,但是直到我发现 exa 之前从来没想过会有命令能替代它。

exa 命令简介

exa 是一个命令行工具,可以列出指定路径(如未指定则是当前目录)的目录和文件。这也许听起来很熟悉,因为这就是 ls 命令所做的事情。

exa 被视作从 UNIX 旧时代延续至今的古老的 ls 命令的一个现代替代品。如其所声称的那样,它有比 ls 命令更多的功能、更好的默认行为。

exa 功能

以下是一些你应该使用 exa 替代 ls 的原因:

  • exals 一样可移植(在所有主流 Linux 发行版、*BSD 和 macOS 上可用)
  • 默认彩色输出
  • exa 不同格式化的“详细”输出也许会吸引 Linux/BSD 新手
  • 文件查询是并行进行的,这使得 exals 的性能相当
  • 显示单个文件的 git 暂存或未暂存状态

exa 的另外一个不同的地方是它是用 Rust 编写的。顺便说一句,Rust 与 C 语言的执行速度相近,但在编译时减少了内存错误,使你的软件可以快速而安全地执行。

在 Linux 系统上安装 exa

exa 最近很流行,因为许多发行版开始将其包括在其官方软件库中。也就是说,你应该可以使用你的 [发行版的包管理器] 来安装它。

从 Ubuntu 20.10 开始,你可以使用 apt 命令来安装它:

1
sudo apt install exa

Arch Linux 已经有了它,你只需要 使用 pacman 命令即可:

1
sudo pacman -S exa

如果它无法通过你的包管理器安装,请不要担心。毕竟它是一个 Rust 包,你可以很容易地用 Cargo 安装它。请确保在你使用的任何发行版 或 Ubuntu 上安装了 Rust 和 Cargo

安装 Rust 和 Cargo 后,使用此命令安装 exa

1
cargo install exa

使用 exa

exa 有很多命令选项,主要是为了更好的格式化输出和一些提高舒适度的改进,比如文件的 git 暂存或未暂存状态等等。

下面是一些屏幕截图,展示了 exa 是如何在你的系统上工作的。

简单地使用 exa 命令将产生类似于 ls 但带有颜色的输出。这种彩色的东西可能没有那么吸引人,因为像 Ubuntu 这样的发行版至少在桌面版本中已经提供了彩色的 ls 输出。不过,ls 命令本身默认没有彩色输出。

1
exa
exa 命令的输出截图,没有任何额外的标志

请注意,exals 命令的选项不尽相同。例如,虽然 -l 选项在 exals 中都给出了长列表,但 -h 选项添加了一个列标题,而不是 ls 的人类可读选项。

1
exa -lh
正如我之前提到的,exa 有列标题以获得更好的“详细”输出

我前面说过,exa 已经内置了 Git 集成。下面的屏幕截图给出了 –git 标志的演示。请注意 test_filegittracked 列中显示 -N ,因为它尚未添加到存储库中。

1
exa --git -lh
演示 git 标志如何与 exa 一起工作

下面的例子不是我的猫键入的。它是各种选项的组合。exa 有可供你尝试和探索的很多选项。

1
exa -abghHliS

你可以通过在终端中运行以下命令来获取完整的选项列表:

1
exa --help

但是,如果你想了解 exa 所提供的功能,可以查看其 Git 存储库 上的 官方文档。值得从 ls 切换到 exa 吗?

对于类 UNIX 操作系统的新手来说,exa 可能是用户友好的,它牺牲了在脚本中容易使用的能力,以换取“易用性”和外观。其中,显示得更清楚并不是一件坏事。

无论如何,ls 就像通用命令。你可以将 exa 用于个人用途,但在编写脚本时,请坚持使用 ls。当预期输出与任一命令中的实际输出不匹配时,ls 和 exa 之间一个 [或多个] 标志的差异可能会让你发疯。

我想知道你对 exa 的看法。你已经尝试过了吗?你对它的体验如何?

但是,如果你想了解 exa 所提供的功能,可以查看其 Git 存储库 上的 官方文档

值得从 ls 切换到 exa 吗?

对于类 UNIX 操作系统的新手来说,exa 可能是用户友好的,它牺牲了在脚本中容易使用的能力,以换取“易用性”和外观。其中,显示得更清楚并不是一件坏事。

无论如何,ls 就像通用命令。你可以将 exa 用于个人用途,但在编写脚本时,请坚持使用 ls。当预期输出与任一命令中的实际输出不匹配时,lsexa 之间一个 [或多个] 标志的差异可能会让你发疯。

我想知道你对 exa 的看法。你已经尝试过了吗?你对它的体验如何?

本文转自 exa:一个 ls 命令的现代替代品,如有侵权,请联系删除。

Zsh中实现快速路径跳转, 之前已经介绍了z.luaZsh配置快速路径跳转)。今天看到了另一个zsh的插件zoxide, 它是用rust语言写的,所以效率上应当是更高的。至于为什么会由z.lua切换到zoxide, 这里我也想不出更好的理由,但是大家可以参考文章zoxide VS z.luazsh-z VS zoxide, 今天我是做为尝试而切换到zoxide, 当然z.lua依然优秀。

zoxide 简介

zoxide is a smarter cd command, inspired by z and autojump.

It remembers which directories you use most frequently, so you can "jump" to them in just a few keystrokes.zoxide works on all major shells.

Getting started

1
2
3
4
5
6
7
8
9
10
11
12
z foo              # cd into highest ranked directory matching foo
z foo bar # cd into highest ranked directory matching foo and bar
z foo / # cd into a subdirectory starting with foo

z ~/foo # z also works like a regular cd command
z foo/ # cd into relative path
z .. # cd one level up
z - # cd into previous directory

zi foo # cd with interactive selection (using fzf)

z foo<SPACE><TAB> # show interactive completions (zoxide v0.8.0+, bash 4.4+/fish/zsh only)

Installation

install zoxide
1
sudo pacman -S zoxide

Configure

~/.zshrc
1
2
3
4
5
6
# set for zsh-z-git
# source /usr/share/zsh/plugins/zsh-z/zsh-z.plugin.zsh
# set for z.lua 功能上不如zsh-z-git完善
# eval "$(lua /usr/share/z.lua/z.lua --init zsh enhanced once)"
# set for zoxide instead of z.lua
eval "$(zoxide init zsh)"

对比配置信息来看,zoxide 好像更加简洁一些,但是这不是主要的切换依据,几个工具都可以尝试。我认为z.lua是从aur中安装的,但是zoxide是从Archlinux的官方仓库中安装,使用官方的工具我认为更可靠一些。

Import your data

If you currently use any of these plugins, you may want to import your data

autojump

Run this command in your terminal:

1
zoxide import --from=autojump "/path/to/autojump/db"

The path usually varies according to your system:

OS Path Example
Linux $XDG_DATA_HOME/autojump/autojump.txt or $HOME/.local/share/autojump/autojump.txt /home/alice/.local/share/autojump/autojump.txt
macOS $HOME/Library/autojump/autojump.txt /Users/Alice/Library/autojump/autojump.txt
Windows %APPDATA%\autojump\autojump.txt C:\Users\Alice\AppData\Roaming\autojump\autojump.txt
fasd, z, z.lua, zsh-z

Run this command in your terminal:

1
zoxide import --from=z "path/to/z/db"

The path usually varies according to your system:

Plugin Path
fasd $_FASD_DATA or $HOME/.fasd
z (bash/zsh) $_Z_DATA or $HOME/.z
z (fish) $Z_DATA or $XDG_DATA_HOME/z/data or $HOME/.local/share/z/data
z.lua (bash/zsh) $_ZL_DATA or $HOME/.zlua
z.lua (fish) $XDG_DATA_HOME/zlua/zlua.txt or $HOME/.local/share/zlua/zlua.txt or $_ZL_DATA
zsh-z $ZSHZ_DATA or $_Z_DATA or $HOME/.z
ZLocation

Run this command in PowerShell:

1
2
3
$db = New-TemporaryFile
(Get-ZLocation).GetEnumerator() | ForEach-Object { Write-Output ($_.Name+'|'+$_.Value+'|0') } | Out-File $db
zoxide import --from=z $db

介绍

各种规范指定文件和文件格式。此规范通过定义相对于哪些文件应该位于的一个或多个基本目录来定义应该查找这些文件的位置。

基本

XDG基本目录规范基于以下概念:

  • 有一个用于写入特定用户数据文件的基本目录。$XDG_DATA_HOME。
  • 有一个用于写入特定用户的配置文件基本目录。$XDG_CONFIG_HOME。
  • 有一组首选的基本数据目录。$XDG_DATA_DIRS。
  • 有一组首选的基本配置目录。$XDG_CONFIG_DIRS。
  • 有一个用于写入用户特定的非必要(缓存)数据的基本目录。$XDG_CACHE_HOME。
  • 有一个用户放置特定于用户的运行时文件和其他文件对象。$XDG_RUNTIME_DIR。

环境变量

XDG环境变量 默认值
$XDG_DATA_HOME $HOME/.local/share
$XDG_CONFIG_HOME $HOME/.config
$XDG_DATA_DIRS /usr/local/share/:/usr/share/
$XDG_CONFIG_DIRS /etc/xdg
$XDG_CACHE_HOME $HOME/.cache

$XDG_RUNTIME_DIR是用户特定的不重要的运行时文件和其他文件对象(例如套接字,命名管道…)存储的基本目录。该目录必须由用户拥有,并且他必须是唯一具有读写访问权限的目录。它的Unix访问模式必须是0700。

目录的生命周期必须绑定到登录用户。必须在用户首次登录时创建,如果用户完全注销,则必须删除该目录。如果用户多次登录,他应该指向同一目录,并且必须从第一次登录到他在系统上的最后一次登出时继续存在,而不是在两者之间删除。目录中的文件必须不能在重新启动或完全注销/登录循环后继续存在。

该目录必须位于本地文件系统上,不与任何其他系统共享。该目录必须完全按照操作系统的标准进行。更具体地说,在类Unix操作系统上,AF_UNIX套接字,符号链接,硬链接,适当的权限,文件锁定,稀疏文件,内存映射,文件更改通知,必须支持可靠的硬链接计数,并且对文件名没有限制应该强加字符集。此目录中的文件可能需要定期清理。为确保不删除您的文件,他们应至少每6小时单调时间修改一次访问时间戳记,或者在文件上设置“粘滞”位。

如果$XDG_RUNTIME_DIR未设置,应用程序应回退到具有类似功能的替换目录并打印警告消息。应用程序应使用此目录进行通信和同步,并且不应在其中放置较大的文件,因为它可能驻留在运行时内存中,并且不一定可以交换到磁盘。

参考规范

文件 参考规范:subdir应该为软件名
数据文件 $datadir/subdir/filename
配置文件 $confdir/subdir/filename

$config默认为~/.config : /etc
如果在尝试编写文件时,目标目录不存在,则应尝试使用权限创建目标目录0700。如果目标目录已存在,则不应更改权限。应用程序应准备好处理无法写入文件的情况,因为该目录不存在且无法创建,或者出于任何其他原因。在这种情况下,它可以选择向用户呈现错误消息。

参考文章