2017-05-25 43 views
0

新建shell脚本,我想测试一下,看看是否我创建的变量是有效的目录,如果没有用户发送到while循环进入目录,只允许出口输入一个有效的目录时。如何将“if”和“while循环”语句组合在一起?

到目前为止,这是我的脚本是这样的:

~/bin/bash 
source_dir="$1" 
dest_dir="$2" 

mkdir /#HOME/$source_dir 
mkdir /#HOME$dest_dir 


if [ -d "$source_dir" ] 
then 
     echo "$source_dir is a valid directory" 
fi 

while [[ ! -d "$source_dir" ]] 
do 
     echo "Please enter a valid directory" 
     read source_dir 
done 

有没有办法将这些组合成一个单一的声明?

+0

没有什么错你的方法。不过,如果您将* if *的else分支内的*移动*,我会认为您的代码的意图更易于理解。然而,这是编程风格的一般问题,并且与shell脚本无关。 – user1934428

回答

2

while code will never如果目录有效,则执行。因此只要将echo "$source_dir is a valid directory"在循环之后:

#!/bin/bash 
source_dir="$1" 
dest_dir="$2" 

mkdir "$HOME/$source_dir" 
mkdir "$HOME/$dest_dir" 

until [[ -d "$source_dir" ]] 
do 
     read -p "Please enter a valid directory" source_dir 
done 
echo "$source_dir is a valid directory" 

注:

  • 几个代码错别字进行固定,例如/#HOME$dest_dir应该是"$HOME/$dest_dir"

  • 任何while !可缩短至until

上面的代码没有几件事情:

  • 它试图创建一个新目录,如果失败,已经让用户输入一个已经存在的目录。这可能是更好的让用户创建一个新的目录,但只有当它不存在。

  • 这将是更好地检查是否存在$dest_dir

下面是一个使用壳功能的更彻底的方法:

#!/bin/bash 
untilmkdir() 
{ 
    d="$1"; 
    until mkdir "$d" ; do 
     read -p "Please enter a valid directory: " d 
     [ -d "$d" ] && break 
    done; 
    echo "$d is a valid directory" 1>&2 
    echo "$d" 
} 

source_dir=$(untilmkdir "$HOME/$1") 
dest_dir=$(untilmkdir "$HOME/$2") 

注:

  • untilmkdir的提示被印刷到stderr的
  • 的任何目录untilmkdir创建打印到标准输出名称。
  • 已将untilmkdir打印到stderr标准输出允许将成功创建的名称存储到变量中。
+0

我认为这是重点。如果目录已经存在,循环**应该不会被执行。 – user1934428

+0

@ user1934428,'!mkdir foo'只在* foo *不存在的情况下返回* true *,因此除非需要循环,否则循环从不执行。在这里,错误的“if”和错误的“while”在功能上是等同的。 – agc

+0

鲜为人知的事实:有一个由POSIX定义的“直到”循环。 '直到mkdir“$ HOME/$ source_dir”2>/dev/null;做' – chepner