相关疑难解决方法(0)

shell脚本可以设置调用shell的环境变量吗?

我正在尝试编写一个shell脚本,在运行时,将设置一些将在调用者的shell中保留的环境变量.

setenv FOO foo
Run Code Online (Sandbox Code Playgroud)

在csh/tcsh中,或

export FOO=foo
Run Code Online (Sandbox Code Playgroud)

在sh/bash中只在脚本执行期间设置它.

我已经知道了

source myscript
Run Code Online (Sandbox Code Playgroud)

将运行脚本的命令而不是启动新的shell,这可能导致设置"调用者"环境.

但这里有一个问题:

我希望这个脚本可以从bash或csh调用.换句话说,我希望任何一个shell的用户都能够运行我的脚本并改变他们的shell环境.所以'source'对我来说不起作用,因为运行csh的用户无法获取bash脚本,而运行bash的用户无法获取csh脚本.

有没有合理的解决方案不需要在脚本上编写和维护两个版本?

bash shell csh tcsh

396
推荐指数
8
解决办法
46万
查看次数

在Bash中,如何找到编号最小的未使用文件描述符?

在Bash脚本中,是否可以在"尚未使用的编号最小的文件描述符"上打开文件?

我四处寻找如何做到这一点,但似乎Bash总是要求你指定数字,例如:

exec 3< /path/to/a/file    # Open file for reading on file descriptor 3.
Run Code Online (Sandbox Code Playgroud)

相反,我希望能够做类似的事情

my_file_descriptor=$(open_r /path/to/a/file)
Run Code Online (Sandbox Code Playgroud)

这将打开'file'以读取尚未使用的编号最小的文件描述符,并将该编号分配给变量'my_file_descriptor'.

bash file-io

40
推荐指数
4
解决办法
6965
查看次数

用于`ls`中的名称和带空格的文件名

由于文件名中的空格,下一个代码不起作用,如何修复?

IFS = '\n'
for name in `ls `
do
    number=`echo "$name" | grep -o "[0-9]\{1,2\}"`
    if [[ ! -z "$number" ]]; then
        mv "$name" "./$number"
    fi
done
Run Code Online (Sandbox Code Playgroud)

bash filenames special-characters

23
推荐指数
3
解决办法
3万
查看次数

如何使用NULL(\ 0)作为GNU排序中的分隔符

我正在寻找一种方法来排序find正确返回多个目录的结果,以便在bash脚本中进一步处理.因为文件名不能包含NULL(\ 0)字符,我认为这将为管道传输的结果提供一个很好的分隔符sort.

所以这就是我期望的工作方式:

find ./ -maxdepth 1 -type d -iname 'xyz?' -print0 | sort -t $'\0'
Run Code Online (Sandbox Code Playgroud)

但遗憾的是我得到了复杂 sort: empty tab

环顾四周寻找解释时遇到了一个类似的结果,这个结果被认为是正常工作(参见11月26日的卢卡斯评论).在我的情况下(使用GNU sort v 7.4),这似乎是不同的.

我还通过管道输入检查了find的输出,od -c但这只显示结果文件夹按预期分隔为NULL.

有没有人在这里遇到类似的情况,并可能找到一个解决方案或解释为什么\ 0似乎是一个不可能的排序分类?

期待你的回答......

编辑:请注意这里使用find-command作为示例,一种更简单的方法来测试/说明这可能echo "g\0u\0b\0k" | sort -t $'\0'

sorting bash

13
推荐指数
1
解决办法
8002
查看次数

Bash:使用文件名中的空格展开大括号和全局?

我有一些文件看起来像:

/path/with spaces/{a,b,c}/*.gz
Run Code Online (Sandbox Code Playgroud)

我需要在a,b,cdirs 子集下匹配glob的所有文件最终作为单个命令的参数:

mycmd '/path/with spaces/a/1.gz' '/path/with spaces/a/2.gz' '/path/with spaces/c/3.gz' ...
Run Code Online (Sandbox Code Playgroud)

我关心的目录作为命令行参数进入,我将它们放在一个数组中:

dirs=( "$@" )
Run Code Online (Sandbox Code Playgroud)

我想做的事情如下:

IFS=,
mycmd "/path/with spaces/{${dirs[*]}}/"*.gz
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为bash在变量之前扩展括号.我曾尝试过使用echols甚至eval(*shudder*)的技巧,但很难让它们与文件名中的空格一起使用. find似乎没有多大帮助,因为它没有做括号.我可以为数组中的每个目录获取一个单独的glob:

dirs=( "${dirs[@]/#//path/with spaces/}" )
dirs=( "${dirs[@]/%//*.gz}" )
Run Code Online (Sandbox Code Playgroud)

但随后bash在扩展时引用了通配符.

那么:是否有一种优雅的方法可以使所有文件与变量括号和glob模式匹配,正确处理空间,还是我坚持做循环?如果这有所作为,我正在使用Bash 3.

bash filenames glob

10
推荐指数
2
解决办法
6043
查看次数

在terminal/bash脚本中将文件夹拆分为多个子文件夹

我有几个文件夹,每个文件夹有15,000到40,000张照片.我希望将每个文件拆分为子文件夹 - 每个文件夹中包含2,000个文件.

有什么快速的方法可以创建我需要的每个文件夹并移动所有文件?

目前我只能找到如何将文件夹中的前x个项目移动到预先存在的目录中.为了在包含20,000个项目的文件夹上使用它...我需要手动创建10个文件夹,并运行命令10次.

ls -1  |  sort -n | head -2000| xargs -i mv "{}" /folder/
Run Code Online (Sandbox Code Playgroud)

我尝试将它放入for循环中,但是在使用mkdir正确制作文件夹时遇到了麻烦.即使我解决了这个问题,我还是需要程序只为每个第20个文件创建文件夹(新组的开始).它想为每个文件创建一个新文件夹.

那么......我怎样才能轻松地将大量文件移动到每个文件中任意数量文件的文件夹中?

任何帮助都会......非常......乐于助人!

directory bash mv filestructure

9
推荐指数
4
解决办法
2万
查看次数

从管道命令附加到数组变量

我正在编写一个bash函数来获取所有git存储库,但是当我想将所有git存储库路径名存储到数组时,我遇到了一个问题patharray.这是代码:

gitrepo() {
    local opt

    declare -a patharray
    locate -b '\.git' | \
        while read pathname
        do
            pathname="$(dirname ${pathname})"
            if [[ "${pathname}" != *.* ]]; then
            # Note: how to add an element to an existing Bash Array
                patharray=("${patharray[@]}" '\n' "${pathname}")
                # echo -e ${patharray[@]}
            fi
        done
    echo -e ${patharray[@]}
}
Run Code Online (Sandbox Code Playgroud)

我想将所有存储库路径保存到patharray数组中,但是我无法将pipeline其包含在包含locatewhile命令的范围之外.
但是我可以在pipeline命令中获取数组,# echo -e ${patharray[@]}如果取消注释,注释命令运行良好,那么我该如何解决问题呢?

我已经尝试过该export命令,但似乎无法将其传递patharray给管道.

arrays bash pipeline

5
推荐指数
2
解决办法
993
查看次数

Bash脚本将目录文件读入Array

我在使用bash将文件读入数组时遇到问题.

我注意到人们不建议使用ls -1选项.有办法解决这个问题吗?

bash

3
推荐指数
1
解决办法
1万
查看次数

如何在bash的while循环中将条目附加到数组?

当我在 bash 中声明一个数组时,$ ARRAY=('ele1' ele2')我可以使用$ ARRAY+=('ele3').

echo ${ARRAY[@]}
ele1 ele2 ele3
Run Code Online (Sandbox Code Playgroud)

但是,在 while 循环中的脚本中,我无法使其正常工作:

FOUNDFILES=$(ls -lA)
LINE_CNT=1
ARRAY=()

echo -e "$FOUNDFILES" | while read line
        do
                ARRAY+=("test")
                LINE_CNT=$((LINE_CNT+1))
        done

echo "${ARRAY[@]}"
echo $LINE_CNT
Run Code Online (Sandbox Code Playgroud)

LINE_CNT变量提供了找到的文件数量,但我的数组保持为空。我究竟做错了什么?

bash

2
推荐指数
1
解决办法
61
查看次数