Bash shell脚本中的移位优于重新赋值

Bash shell脚本中的移位优于重新赋值,bash,Bash,我不理解以下代码中的shift: #! /usr/local/bin/bash # process command line options interactive= filename= while [[ -n $1 ]]; do case $1 in -f | --file) shift #don't understand the shift #No.1

我不理解以下代码中的
shift

    #! /usr/local/bin/bash
    # process command line options
    interactive=
    filename=
    while [[ -n $1 ]]; do
        case $1 in 
            -f | --file)    shift #don't understand the shift #No.1
                            filename=$1 ;;
            -i | --interactive) interactive=1
                                ;;
            -h | --help)    usage
                            exit;;
            *)              echo "usage >&2 exit 1";;
        esac
        shift # don't understand the shift #2
    done

    #interactive mode
    if [[ -n $interactive ]]; then
       echo "do something"
    fi
    #output html page
    if [[ -n $filename ]]; then
        if touch $filename && [[ -f $filename ]]; then
           echo "write_html_page > $filename" #debug 
        else
            echo "$program: Cannot write file $filename " >&2
            exit 1
        fi
    else
        echo "write_html_page to terminal" # debug
    fi
测试一下

    $ bash question.sh -f test
    write_html_page > test

    $ bash question.sh -f
    write_html_page to terminal
当我删除
shift
并将
filename=$1
更改为
filename=$2

    $ bash question.sh -f
    write_html_page to terminal
  # it works properly

    $ bash question.sh -f test
    usage >&2 exit 1
    write_html_page > test 
  # it almost function  nicely except that `usage >&2 exit 1` is executed.
因此,
shift
不能完全替换为
filename=$2

在botton的第二个班次如果被删除,循环将无休止地运行

我能直观地解释
shift
吗?

我在其他语言中找不到如此神奇的命令。

本页示例:

解释它在做什么

编辑:

例如:

通常在命令的参数数量事先未知时使用shift语句,例如,当用户可以提供任意数量的参数时。在这种情况下,参数通常在测试条件为($#)的while循环中处理。只要参数数大于零,此条件为真。$1变量和shift语句处理每个参数。每次执行移位时,参数的数量都会减少,最终变为零,while循环退出


本页的示例如下:

解释它在做什么

编辑:

例如:

通常在命令的参数数量事先未知时使用shift语句,例如,当用户可以提供任意数量的参数时。在这种情况下,参数通常在测试条件为($#)的while循环中处理。只要参数数大于零,此条件为真。$1变量和shift语句处理每个参数。每次执行移位时,参数的数量都会减少,最终变为零,while循环退出


shift
将删除第一个位置参数,并将每隔一个参数左移一次

例如,让我们考虑以下内容:

#!/bin/bash
echo "$@"
shift
echo "$@"
shift
echo "$@"
假设
echo“$@”
将打印所有参数,如果要运行此操作,则会发生以下情况:

./test.bash 1 2 3 4 5

echo "$@"  # prints 1 2 3 4 5
shift      # Removes 1 and shifts everything else along
echo "$@"  # prints 2 3 4 5
shift      # shifting again
echo "$@"  # prints 3 4 5
在您的示例中,脚本正在解析所有标志
-i
-h
只是开关,不处理以下参数。但是,
-f
需要
文件名

第二个
shift
将处理标志,移动参数,然后再次处理它们。因此,您可以使用
/program.bash-i-f文件名
-i
将被第二次移位,然后文件名将在下一个循环中处理

如果要运行
/program.bash-f filename-i
,则需要将
文件名
-f
一起移动。因此,在
-f
的case块上有一个额外的移位。在本例中,
-f
将在case块内移位,然后
文件名
将移位第二个
移位
。然后循环将再次运行以处理任何进一步的标志


由于while循环是
[[-n$1]]
,因此循环将一直运行,直到不再有参数。

shift
将删除第一个位置参数,并每隔一个参数向左移动一次

例如,让我们考虑以下内容:

#!/bin/bash
echo "$@"
shift
echo "$@"
shift
echo "$@"
假设
echo“$@”
将打印所有参数,如果要运行此操作,则会发生以下情况:

./test.bash 1 2 3 4 5

echo "$@"  # prints 1 2 3 4 5
shift      # Removes 1 and shifts everything else along
echo "$@"  # prints 2 3 4 5
shift      # shifting again
echo "$@"  # prints 3 4 5
在您的示例中,脚本正在解析所有标志
-i
-h
只是开关,不处理以下参数。但是,
-f
需要
文件名

第二个
shift
将处理标志,移动参数,然后再次处理它们。因此,您可以使用
/program.bash-i-f文件名
-i
将被第二次移位,然后文件名将在下一个循环中处理

如果要运行
/program.bash-f filename-i
,则需要将
文件名
-f
一起移动。因此,在
-f
的case块上有一个额外的移位。在本例中,
-f
将在case块内移位,然后
文件名
将移位第二个
移位
。然后循环将再次运行以处理任何进一步的标志


由于while循环是
[[-n$1]]
,循环将一直运行,直到没有更多参数。

案例中的
移位
是否不影响
上的值,而[[-n$1]]
`-f |--file)shift`此移位会在[-n$1]]
时更改
的值,ty,我明白你的意思了。就像popleft数组一样。是的,就像popleft数组一样。但是您需要使用
-f
弹出两次。假设第二个移位在每次迭代中都会弹出,我们只需要为
-f
再弹出一次,因此为什么也需要第一个移位。在
案例中的
移位
是否不会影响
上的值,而[[-n$1]]
`-f |--file)移位`此移位会在[-n$1]
时更改
的值,我知道你的想法。就像popleft数组一样。是的,就像popleft数组一样。但是您需要使用
-f
弹出两次。鉴于每次迭代都会弹出第二个移位,我们只需要再弹出一次
-f
,因此也需要第一个移位。
shift
允许上面的代码在循环中解析命令行,而不考虑选项的顺序(
-f
-i
-h
等)。使用
shift
,循环在每次迭代中使用一个(或两个)命令行参数(已解释的参数)。
shift
允许上面的代码在循环中解析命令行,而不考虑选项的顺序(
-f
-i
-h
等)