【问题标题】:lftp: how to recursively set permissions; firstly by directory than by filelftp:如何递归设置权限;首先按目录而不是按文件
【发布时间】:2012-12-13 12:23:33
【问题描述】:

当在不公开 SSH 访问的共享主机上保护 Drupal 或 WordPress 安装时(糟糕的情况,fwiw),lftp 似乎是批量设置目录和文件权限的正确方法。 find 命令吹嘘你可以重定向它的输出,所以应该能够运行 find,grep exclude 以仅匹配以“/”结尾的行,表示目录,然后将此类匹配的权限设置为 755 并执行相反的操作对文件匹配并设置为 644,然后微调特定文件,例如 settings.php 等。

lftp prompt> find . | grep "/$" | xargs chmod -v 755 

不起作用,我确定我未能以正确的顺序和格式链接这些命令。

如何让它工作?

更新:“不工作”我的意思是上面的命令没有输出到控制台,也没有输出到 lftp 错误日志。它不是在本地运行这些命令,fwiw。我将减少命令作为演示:

find . | grep "/$"

将获取“find”的输出并返回匹配项,这里是目录,按字符串匹配的性质:

./daily/
./ffmpeg-installer/
./hourly/
./includes/
./includes/database/
./includes/database/mysql/
./and_so_forth_on_down

这很酷,因为我希望执行 chmod(以及 lftp 的内部命令,支持因 ftp 服务器而异)所以我像这样扩展命令:

find . | grep "/$" | xargs echo

哪些输出——什么都没有。也没有错误输出。从 grep 到 xargs 的管道没有发生。

我的目标是形成以下等价物:

chmod 755 ./daily/
chmod 755 ./ffmpeg-installer/

在 lftp 中,chmod 命令正在执行 ftp-server-permissions 更改,不是本地权限更改。

【问题讨论】:

    标签: ftp file-permissions shared-hosting batch-processing lftp


    【解决方案1】:

    要了解为什么这不能按预期工作,请继续阅读 - 要了解给定问题的解决方案,请向下滚动。

    可以在lftp 的手册页中找到答案,其中指出

    “[s]ome 命令允许将其输出(cat、ls、...)重定向到文件或通过管道重定向到外部命令。”

    因此,当您在lftp 中支持重定向的命令上使用这样的管道时,您会将其输出通过管道传输到您的 local 工具,这最终将导致 chmod尝试在我们的 local 机器上更改文件/目录的权限,如果您在本地当前目录中的目录布局不同,很可能会失败 - 这可能是您的问题遇到过。

    grep + xargs 管道确实有效,我刚刚测试了以下内容:

    lftp> find -d 2 | grep "/$"
    ./
    ./applications/
    ./lost+found/
    ./netinfo/
    ./packages/
    ./security/
    ./systems/
    lftp> find -d 2 | grep "/$" | xargs echo
    ./ ./applications/ ./lost+found/ ./netinfo/ ./packages/ ./security/ ./systems/
    

    我的疯狂猜测是,它似乎对您不起作用,因为您没有指定要查找的最大深度,并且管道中的网络连接 + 缓冲妨碍了您。当我在包含许多文件/子文件夹的目录上尝试相同的操作时,完成和打印需要很长时间。该命令实际上是否为您完成但没有输出?

    但是,您尝试做的事情仍然是不可能的。正如我所说,管道的右侧与手册中解释的external命令(即使存在同名的内置命令)一起使用,所以

    lftp> chmod 644 foobar
    

    lftp> echo "foobar" | xargs chmod 644
    

    等效。 是的,chmod 是内置的,但在客户端的管道中使用它不会执行内置 - 手册页清楚地说明了这一点,您可以自己轻松测试。尝试以下命令并检查其输出:

    lftp> echo foo | uname -a
    lftp> echo foo | ls -al
    lftp> echo foo | chmod --help
    lftp> chmod --help
    

    解决方案

    就您的问题的解决方案而言,您可以尝试以下方式:

    #!/bin/bash
    
    server="ftp.foo.bar"
    root_folder="/my/path"
    
    {
            {
                    lftp "${server}" <<EOF
                    cd "${root_folder}"
                    find | grep "/$"
                    quit
    EOF
            } | awk '{ printf "chmod 755 \"%s\"\n", $0 }'
    
            {
                    lftp "${server}" <<EOF
                    cd "${root_folder}"
                    find | grep -v "/$"
                    quit
    EOF
            } | awk '{ printf "chmod 644 \"%s\"\n", $0 }'
    } | lftp "${server}"
    

    这将登录到您的服务器,cds 到您要递归开始更改权限的文件夹,使用 find + grep 查找所有目录,注销,将此文件列表通过管道传输到 awk 以构建 @ 987654335@ 围绕它的命令,重复文件的整个过程,然后将整个命令列表通过管道传输到新的lftp 调用中,以实际运行生成的chmod 命令。

    您还必须将您的凭据添加到 lftp 调用中,并且您可能想要注释掉最终的 | lftp "${server}" 以在您实际运行整个过程之前检查它是否产生所需的输出。如果这对您有用,请报告!

    【讨论】:

    • 不,lftp 手册页的引用是一种解释,但不是答案。这个问题仍然没有答案。我写的命令的行为不符合你的猜测,fwiw。也没有错误输出。所以也许提供一些粒度可能会有所帮助?我会相应地更新我的主要问题。
    • @Kyle 感谢您的更新!不,您对正在发生的事情的理解是不正确的(根据手册页的引用),我更新了我的答案以说明原因。
    • @Kyle 好吧,不可能像您尝试的那样一次性完成,但可以使用您最初的 find/grep 管道作为基础编写脚本,请参阅我的更新答案。
    • 这太棒了。我目前没有可以对其进行全面测试的网站,但根据我的飞行前检查,(根据您的建议)这非常适合我正在寻找的东西。我仍然会恳求我的客户允许 ssh 连接,并将其用于顽固的连接。一些 cmets:lftp 允许您定义书签,其作用类似于别名。因此,在准备过程中,您可以定义相关服务器的别名,然后将其传递给 $server shell 变量。如果时间允许,我会扩展它,以便可以将它作为 arg 传递到脚本中。顺便说一句,将文件设置为 644 很不错。
    • @Kyle 完美!关于书签功能的好提示,如果以后这让您头疼,请回来查看,因为我只是自己快速测试了一下:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 1970-01-01
    • 2016-08-01
    • 2018-04-26
    • 1970-01-01
    • 2013-07-11
    • 2023-03-10
    相关资源
    最近更新 更多