bash - 自动从大写目录创建具有小写名称的符号链接(symbolic link)

标签 bash active-directory sh symlink samba

感谢您考虑提供帮助。

我正在尝试创建一个简单的 shell 脚本,该脚本运行后将查看文件夹中通常为大写形式的所有目录,并以小写形式创建到该目录的符号链接(symbolic link)。然后,当新文件夹添加到目录中时,我将定期执行此脚本,以创建指向新文件夹的附加符号链接(symbolic link)。该脚本必须了解已为其创建符号链接(symbolic link)的其他文件夹,以免造成任何停止问题或错误。下面是我试图实现的目标的可视化。

drwxr-xr-x 2 root root 4096 Jun 18 03:52 Holmes
drwxr-xr-x 2 root root 4096 Jun 18 03:52 Kingship
-rwxrwxrwx 1 root root   85 Jun 18 04:39 link.sh
drwxr-xr-x 2 root root 4096 Jun 18 03:52 Lost
drwxr-xr-x 2 root root 4096 Jun 18 03:52 Monkey
drwxr-xr-x 2 root root 4096 Jun 18 03:52 Space Ship
drwxr-xr-x 2 root root 4096 Jun 18 03:52 Test

lrwxrwxrwx  1 root root    6 Jun 18 04:49 holmes -> Holmes
drwxr-xr-x  2 root root 4096 Jun 18 03:52 Holmes
lrwxrwxrwx  1 root root    8 Jun 18 04:49 kingship -> Kingship
drwxr-xr-x  2 root root 4096 Jun 18 03:52 Kingship
-rwxrwxrwx  1 root root   85 Jun 18 04:39 link.sh
lrwxrwxrwx  1 root root    4 Jun 18 04:49 lost -> Lost
drwxr-xr-x  2 root root 4096 Jun 18 03:52 Lost
lrwxrwxrwx  1 root root    6 Jun 18 04:49 monkey -> Monkey
drwxr-xr-x  2 root root 4096 Jun 18 03:52 Monkey
lrwxrwxrwx  1 root root   10 Jun 18 04:49 space ship -> Space Ship
drwxr-xr-x  2 root root 4096 Jun 18 03:52 Space Ship
lrwxrwxrwx  1 root root    4 Jun 18 04:49 test -> Test
drwxr-xr-x  2 root root 4096 Jun 18 03:52 Test

显然,脚本必须能够为稍后创建但还没有符号链接(symbolic link)的文件夹创建新的符号链接(symbolic link)。

我一直在修改其他两个帖子/答案中的语法,除了重新创建各个答案的结果之外,我并没有真正得到任何东西。帖子在这里Using find on subdirectories and create symlinks to all filesBash script to automatically create symlinks to subdirectories in a tree

也许我正在使用错误的方法来解决我的解决方案。我实际上想要实现的是,这是一个 NAS 系统,它具有根据用户名自动创建的文件夹。然后,这些文件夹将通过 samba home 共享自动共享。但是,除非创建小写文件夹,否则无法访问共享,因为这些文件夹最初是使用空格以及用户名的大小写结构创建的。用户名的结构与unix系统并不完全兼容,因为在unix系统上测试和测试是两个不同的东西。我研究了如何允许使用大写字母创建用户名,但是进行这些更改不会影响 samba 共享识别文件夹的方式。

最佳答案

一步一步的方法:

首先,在一个临时目录中,我正在创建一个像您这样的目录示例:

$ mkdir Holmes Kingship Lost Monkey 'Space Ship' Test a_lower_case_one
$ touch just_a_file One_with_UpperCase
$ ln -s Holmes holmes
$ ls -og
total 28
drwxr-xr-x 2 4096 Jun 18 11:54 a_lower_case_one
lrwxrwxrwx 1    6 Jun 18 11:54 holmes -> Holmes
drwxr-xr-x 2 4096 Jun 18 11:54 Holmes
-rw-r--r-- 1    0 Jun 18 11:54 just_a_file
drwxr-xr-x 2 4096 Jun 18 11:54 Kingship
drwxr-xr-x 2 4096 Jun 18 11:54 Lost
drwxr-xr-x 2 4096 Jun 18 11:54 Monkey
-rw-r--r-- 1    0 Jun 18 11:54 One_with_UpperCase
drwxr-xr-x 2 4096 Jun 18 11:54 Space Ship
drwxr-xr-x 2 4096 Jun 18 11:54 Test

现在,您将如何循环浏览您的目录?就像这样:

$ for i in */; do echo "$i"; done
a_lower_case_one/
holmes/
Holmes/
Kingship/
Lost/
Monkey/
Space Ship/
Test/

如何在 bash 中将变量转换为小写?根据this section of the bash reference manual${i,,} 的扩展将是 $i 小写的扩展:

$ for i in */; do echo "$i -> ${i,,}"; done
a_lower_case_one/ -> a_lower_case_one/
holmes/ -> holmes/
Holmes/ -> holmes/
Kingship/ -> kingship/
Lost/ -> lost/
Monkey/ -> monkey/
Space Ship/ -> space ship/
Test/ -> test/

现在我们只能考虑与其小写扩展不同的目录名称:

$ for i in */; do [[ $i = ${i,,} ]] && continue; echo "$i -> ${i,,}"; done
Holmes/ -> holmes/
Kingship/ -> kingship/
Lost/ -> lost/
Monkey/ -> monkey/
Space Ship/ -> space ship/
Test/ -> test/

对于其中的每一个,我们将测试是否已经存在小写字母:

$ for i in */; do [[ $i = ${i,,} ]] && continue; echo "$i -> ${i,,}"; if [[ -e ${i,,} ]]; then echo "    ${i,,} exists"; fi; done
Holmes/ -> holmes/
    holmes/ exists
Kingship/ -> kingship/
Lost/ -> lost/
Monkey/ -> monkey/
Space Ship/ -> space ship/
Test/ -> test/

当小写字母已经存在时,我们将检查它是否是链接到大写字母的链接。如果是,则一切正常,否则我们将打印警告。因为它变得有点大,我将把它写成 bash 脚本:

#!/bin/bash

for i in */; do
    d=${i%/}
    dl=${d,,}
    [[ $d = $dl ]] && continue
    if [[ -e $dl ]]; then
        if [[ ! -L $dl ]]; then
            echo "    ERROR: $dl is not a link"
        elif [[ $(readlink -- "$dl") != $d ]]; then
            echo "    ERROR $dl exists and doesn't point to $d"
        fi
    else
        ln -sv -- "$d" "$dl"
    fi
done

我使用了我所知道的所有最佳实践,以便拥有一个强大的脚本,并且对于文件名中的有趣符号(空格、连字符等)是安全的。

注意。必须从要处理的目录中调用。如有必要,请在此脚本顶部使用 cd

希望这有帮助!

关于bash - 自动从大写目录创建具有小写名称的符号链接(symbolic link),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17164768/

相关文章:

linux - "rsyslogd"占用170M内存正常吗?

powershell - 使用 LDAP 过滤器使用 Get-ADComputer 搜索多个操作系统

powershell - 从CSV创建映射以获取AD用户

bash - sh 和 Bash 之间的区别

linux - 如何使用 bash 将未知数量的源文件名拆分为指定数量的输出文件

bash - 这个访谈项目表明什么水平的专业知识?取消设置 foo;回音栏 |读 foo; echo $foo

java - src 与构建树时间戳比较如何更快?

Bash:为什么比较优先级对通配符很重要?

bash - shell脚本中的性能问题

windows - 使用 Powershell 在 Active Directory 中更新 Active Directory 用户属性