在bash中管理csv文件中读取动态字段的Unix权限

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在bash中管理csv文件中读取动态字段的Unix权限相关的知识,希望对你有一定的参考价值。

我目前坚持使用bash脚本,该脚本应该能够在处理部分的末尾管理文件和目录的权限。

其实我有4个组件:

  • 源.conf文件和libs(.sh)的主脚本,处理事物,并以.csv文件作为参数调用函数“ApplyPermissionFromCSVFile”,以确保正确设置权限。此函数应处理用于管理文件权限的作业
  • 一个名为“permission_lib.sh”的脚本,它包含多个函数,包括“ApplyPermissionFromCSVFile”函数。这个脚本在主脚本的开头是SOURCED
  • 一个.conf文件,其中包含一些定义为变量的路径,这些变量在主脚本的开头是SOURCED
  • 包含路径(包括“动态路径”,引用conf文件中定义的变量)的.csv文件,用于文件和目录,由ApplyPermissionFromCSVFile函数读取

目前,主脚本运行正常,能够同时提供conf文件和lib文件,但是当我在“ApplyPermissionFromCSVFile”中放入一些调试点时,似乎bash不会解释“动态路径”。

主脚本摘录:

######################################### 
includes 
##################################################

# this section can _almost_ be copied as-is ;-)

nameOfThisScript=$(basename "$BASH_SOURCE[0]")
directoryOfThisScript="$( cd "$( dirname "$BASH_SOURCE[0]" )" && pwd )"


configFile="$directoryOfThisScript/$nameOfThisScript.conf"
functionsFile="$directoryOfThisScript/safeScriptsFunctions.sh"
permissionLib="$directoryOfThisScript/permission_lib.sh"

permissionFile="$directoryOfThisScript/$nameOfThisScript.permissionFile.csv"

for fileToSource in "$configFile" "$functionsFile" "$permissionLib"; do
        source "$fileToSource" 2>/dev/null || 
                echo "File '$fileToSource' not found"
                exit 1
                
done
#Main Loop to read CSV File is called in permissionLib.sh
ApplyPermissionFromCSVFile $permissionFile

conf文件的提取(例如真实文件名替换):

totovariable="/usr/local"
tatavariable="$totovariable/bin"

csv文件的摘录:

$totovariable;someuser;somegroup;0600
$tatavariable;someuser;somegroup;0600

权限lib文件的摘录:

function ApplyPermissionFromCSVFile 
        local csvFileName="$1"
        local fieldNumberFileName=1
        local fieldNumberOwner=2
        local fieldNumberGroupOwner=3
        local fieldNumberPermissions=4

        while read csvLine
        do
                fileName=$(getFieldFromCsvLine "$fieldNumberFileName" "$csvLine")
                fileOwner=$(getFieldFromCsvLine "$fieldNumberOwner" "$csvLine")
                fileGroupOwner=$(getFieldFromCsvLine "$fieldNumberGroupOwner" "$csvLine")
                filePermissions=$(getFieldFromCsvLine "$fieldNumberPermissions" "$csvLine")
                permissionArray[0,0]="$fileName|$fileOwner|$fileGroupOwner|$filePermissions"
                echo "$permissionArray[0,0]"
        done < "$csvFileName"


getFieldFromCsvLine() 
        csvFieldSeparator=';'
        fieldNumber="$1"
        csvLine="$2"
        echo "$csvLine" | cut -d "$csvFieldSeparator" -f "$fieldNumber"

不要为每次迭代时循环覆盖值这一事实而烦恼,这不是这里的目的(但是选项回答:p)。

哪个输出结果:

$totovariable|someuser|somegroup|0600
$tatavariable|someuser|somegroup|0600

Changing owner to someuser:somegroup for file $tatavariable
chown: cannot access '$tatavariable': No such file or directory
Changing permissions to 0600 for file $tatavariable
chmod: cannot access '$tatavariable': No such file or directory

经过一些调查研究,似乎正常如下:

  • conf文件是SOURCED(通过主脚本)
  • lib文件是SOURCED(通过主脚本)
  • csv文件不是SOURCED而是READ(通过lib中的函数)。所以bash将变量内容视为“纯字符串”,而不是变量

问题是,我无法清楚地看到我应该如何以及在哪里将值替换为“pure-string”变量(在.conf文件中定义并由主脚本提供):在主脚本级别?在lib级别使用全局变量?

我找到的实际解决方案:

  • 但替补
  • 使用eval

任何帮助都可以得到赞赏。

答案

解决方案:

fileName=eval echo "$fileName"

由于.csv文件中的路径可能包含“$”符号,因此Bash参数扩展在每种情况下都不起作用。

例子:使用以下csv内容:

$tatavariable;someuser;somegroup;0600
$totovariable/thisotherfile.txt;someuser;somegroup;0660
$totovariable;someuser;somegroup;0600
/home/someuser/lolzy.txt;someuser;somegroup;0666

以下conf文件:

totovariable="/home/someuser/fack"
tatavariable="$totovariable/thisfile.txt"

以下bash代码(基于eval,在大多数情况下不强烈推荐)将适用于每个案例(包含$符号或不符号):

#!/bin/bash

#########################
# Function
#########################

getFieldFromCsvLine() 
        local csvFieldSeparator=';'
        local fieldNumber="$1"
        local csvLine="$2"
        echo "$csvLine" | cut -d "$csvFieldSeparator" -f "$fieldNumber"


#########################
#Core Script
#########################

source configFile.conf

csvFileName="permissionFile.csv"
fieldNumberFileName=1
fieldNumberOwner=2
fieldNumberGroupOwner=3
fieldNumberPermissions=4

while read csvLine
do
        fileName=$(getFieldFromCsvLine "$fieldNumberFileName" "$csvLine")
        fileOwner=$(getFieldFromCsvLine "$fieldNumberOwner" "$csvLine")
        fileGroupOwner=$(getFieldFromCsvLine "$fieldNumberGroupOwner" "$csvLine")
        filePermissions=$(getFieldFromCsvLine "$fieldNumberPermissions" "$csvLine")

        #Managing Variables used as 'Dynamic path'
        fileName=$(eval echo "$fileName")
        echo "Content of \$fileName is $fileName"

done < "$csvFileName"

结果:

[someuser@SAFEsandbox:~]$ ./simpletest.sh
Content of $fileName is /home/someuser/fack/thisfile.txt
Content of $fileName is /home/someuser/fack/thisotherfile.txt
Content of $fileName is /home/someuser/fack
Content of $fileName is /home/someuser/lolzy.txt

以下bash代码(基于bash参数扩展)将抛出错误:

#!/bin/bash

#########################
# Function
#########################

getFieldFromCsvLine() 
        local csvFieldSeparator=';'
        local fieldNumber="$1"
        local csvLine="$2"
        echo "$csvLine" | cut -d "$csvFieldSeparator" -f "$fieldNumber"


#########################
#Core Script
#########################

source configFile.conf

csvFileName="permissionFile.csv"
fieldNumberFileName=1
fieldNumberOwner=2
fieldNumberGroupOwner=3
fieldNumberPermissions=4

while read csvLine
do
        fileName=$(getFieldFromCsvLine "$fieldNumberFileName" "$csvLine")
        fileOwner=$(getFieldFromCsvLine "$fieldNumberOwner" "$csvLine")
        fileGroupOwner=$(getFieldFromCsvLine "$fieldNumberGroupOwner" "$csvLine")
        filePermissions=$(getFieldFromCsvLine "$fieldNumberPermissions" "$csvLine")

        #Managing Variables used as 'Dynamic path'
        fileName=$!fileName
        echo "Content of \$fileName is $fileName"

done < "$csvFileName"

.csv包含$符号时的行为示例:

[someuser@SAFEsandbox:~]$ ./simpletest.sh
./simpletest.sh: line 35: $tatavariable: bad substitution

删除.csv文件中的$符号时的行为示例,但仍有增量路径概念:

[someuser@SAFEsandbox:~]$ ./simpletest.sh
Content of $fileName is /home/someuser/fack/thisfile.txt
./simpletest.sh: line 35: totovariable/thisotherfile.txt: bad substitution

使用bash参数扩展(在大多数情况下建议使用)并不容易,因为它强制管理脚本中的2个案例:

  • 包含前导$或几个$(连接变量路径)的路径
  • 路径不包含前导$或几个$(连接变量路径)

问候

以上是关于在bash中管理csv文件中读取动态字段的Unix权限的主要内容,如果未能解决你的问题,请参考以下文章

在管理员中向 Django 的 export_as_csv 操作添加动态字段

如何使用bash脚本从csv文件中读取特定的整数?

如何处理 bash 脚本读取的 CSV 文件中的逗号

用于将日期和时间列转换为 .csv 中的 unix 时间戳的 Bash 脚本

Bash:按前 4 列对 csv 文件进行排序

bash 使用散列键从 CSV 多列中读取