似乎通常的做法会将 IFS 的设置放在 while 循环之外,以免在每次迭代时重复设置......这只是一种习惯性的“猴子看,猴子做”的风格,就像这只猴子直到我读过man read,还是我在这里错过了一些微妙(或明显明显)的陷阱?
我正在尝试使用 bash 脚本读取文本文件并对每一行执行某些操作。
所以,我有一个看起来像这样的列表:
server1
server2
server3
server4
Run Code Online (Sandbox Code Playgroud)
我想我可以使用 while 循环来循环,如下所示:
while read server; do
ssh $server "uname -a"
done < /home/kenny/list_of_servers.txt
Run Code Online (Sandbox Code Playgroud)
while 循环在 1 次运行后停止,因此只uname -a
在 server1 上运行
但是,使用 cat 的 for 循环可以正常工作:
for server in $(cat /home/kenny/list_of_servers.txt) ; do
ssh $server "uname -a"
done
Run Code Online (Sandbox Code Playgroud)
更令我困惑的是,这也有效:
while read server; do
echo $server
done < /home/kenny/list_of_servers.txt
Run Code Online (Sandbox Code Playgroud)
为什么我的第一个示例在第一次迭代后停止?
假设一个输出文件列表的脚本:
$> bash someScript.sh
path/to/some/file
path/to/the/file/i/want/to/work/with
path/to/yet/another/file
Run Code Online (Sandbox Code Playgroud)
现在我想将第二个文件路径作为另一个命令的参数,例如vim
. 有没有办法直接访问它?
我想指出,我不一定要访问第二个文件,但下次可能是第三个或第 27 个。我希望能够尽可能轻松地选择第 N 行。
现在我用鼠标选择并通过单击鼠标中键插入或使用制表符完成输入路径。现在我想知道是否有更简单的方法。
我自己的解决方案的问题是我必须以这种方式编辑我的所有脚本。如果有一个更通用的解决方案来解决这个问题会很有趣,它可以与任何类型的命令一起使用,例如find
.
巧合的是,我不得不使用我的 ATA-ID-to-device-name 脚本(在这里找到:https : //serverfault.com/questions/244944/linux-ata-errors-translating-to-a-device-name/ 426561#426561 ) 在只读 /
分区上。如果你好奇,它是一个 Ubuntu 恢复控制台,它可以让你访问你的/
分区,但默认情况下它会以只读方式挂载。我对此很高兴,因为否则我可能永远不会发现我的脚本由于特定行而在 R/O 系统上表现得很奇怪,这个:
IFS=: read HostMain HostMid HostSub <<< "$HostFull"
Run Code Online (Sandbox Code Playgroud)
这并不会在没有写权限的工作。不过,我不会认为它会失败。但显然<<<
操作员确实需要将一些临时文件写入某个地方。
但是有没有办法绕过临时文件的创建,或者,有没有办法指定文件的写入位置?在 Ubuntu 恢复控制台中,有——奇怪的是——对/run
目录的写权限,如果我能以某种方式“告诉”read
将临时文件写入其他地方而不是平常,那就可以了。
我有一个包含目录列表的文件。例如
/foo/bar/dir1
/foo/bar/dir2
/foo/bar/dir3
Run Code Online (Sandbox Code Playgroud)
我想创建所有这些目录。这是我所做的:
for dir in $(cat myfile); do mkdir $dir; done
Run Code Online (Sandbox Code Playgroud)
在避免“无用的使用 cat”的同时,这样做的正确方法是什么?
理想情况下,答案将集中在 Ksh88,但我也对其他 shell 感兴趣
我有一组文件,所有文件都以约定命名file_[number]_[abcd].bin
(其中 [number] 是驱动器 0 大小范围内的数字,以 MB 为单位)。即有file_0_a.bin
,file_0_b.bin
,file_0_c.bin
和file_0_d.bin
,然后0
将成为1
等等。
文件数在运行时根据分区的大小计算出来。我需要以伪随机方式删除所有已创建的文件。在我需要能够指定的大小块中,即有 1024 个文件的地方,删除 512,然后删除另一个 512。
我目前有以下功能可以执行此操作,我将其称为所需的次数,但它会逐渐不太可能找到存在的文件,直到它可能永远不会完成。显然,这有点不太理想。
我可以用来以随机顺序删除所有文件的另一种方法是什么?
deleteRandFile() #$1 - total number of files
{
i=$((RANDOM%$1))
j=$((RANDOM%3))
file=""
case $j in
0)
file="${dest_dir}/file_${i}_a.bin";;
1)
file="${dest_dir}/file_${i}_b.bin";;
2)
file="${dest_dir}/file_${i}_c.bin";;
3)
file="${dest_dir}/file_${i}_d.bin";;
esac
if ! [[ -f $file ]]; then
deleteRandFile $1
else
rm $file
fi
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:我试图以随机顺序删除,以便我可以尽可能多地分割文件。这是脚本的一部分,首先用 1MB 文件填充驱动器,然后删除它们,一次 1024 个,然后用 1 个 1GB 文件填充“空白”。冲洗并重复,直到你有一些非常碎片化的 1GB 文件。
我正在尝试创建一个脚本来检查网站上的单词。我有几个要检查,所以我试图通过另一个文件输入它们。
该文件称为“testurls”。在文件中,我先列出关键字,然后列出 URL。它们用分号分隔。
Example Domains;www.example.com
Google;www.google.com
Run Code Online (Sandbox Code Playgroud)
这是脚本:
#!/bin/bash
clear
# Call list of keywords and urls
DATA=`cat testurls`
for keyurl in $DATA
do
keyword=`awk -F ";" '{print $1}' $keyurl`
url=`awk -F ";" '{print $2}' $keyurl`
curl -silent $url | grep '$keyword' > /dev/null
if [ $? != 0 ]; then
# Fail
echo "Did not find $keyword on $url"
else
# Pass
echo $url "Okay"
fi
done
Run Code Online (Sandbox Code Playgroud)
输出是:
awk: cannot open Example (No such file or directory)
awk: cannot open …
Run Code Online (Sandbox Code Playgroud)