如何在鱼壳中获得用户确认?

时间:2013-05-06 21:24:02

标签: user-input confirmation fish

我试图收集鱼类文稿中的用户输入,特别是以下常见形式:

This command will delete some files. Proceed (y/N)?

经过一番搜索后,我仍然不确定如何干净利落。

这是在鱼类中这样做的特殊方式吗?

4 个答案:

答案 0 :(得分:19)

我所知道的最好的方法是使用内置read。如果您在多个地方使用它,您可以创建此辅助函数:

function read_confirm
  while true
    read -l -P 'Do you want to continue? [y/N] ' confirm

    switch $confirm
      case Y y
        return 0
      case '' N n
        return 1
    end
  end
end

并在脚本/函数中使用它:

if read_confirm
  echo 'Do stuff'
end

有关更多选项,请参阅文档: https://fishshell.com/docs/current/commands.html#read

答案 1 :(得分:4)

这与选择的答案相同,但只有一个功能,对我来说似乎更清晰:

class Program
{
    static void Main(string[] args)
    {
        var input = "0 1 2 4 6 7";
        var result = Solve(input);
    }

    private static int Solve(string input)
    {
        var digits = input.Split(' ').Select(i => int.Parse(i)).ToArray();
        return GetSmallestDifference(digits) ?? -1;
    }

    public static int? GetSmallestDifference(IEnumerable<int> input)
    {
        var validInput = ValidateInput(input);

        var candidates = GenerateCandidates(validInput);

        int? best = null;
        foreach (var candidate in candidates)
        {
            var current = Math.Abs(candidate.Item1 - candidate.Item2);
            if (current < (best ?? int.MaxValue))
            {
                best = current;
            }
        }
        return best;
    }

    private static IEnumerable<Tuple<int, int>> GenerateCandidates(int[] validInput)
    {
        var found = new HashSet<string>();

        var nonZeroDigits = validInput.Except(new[] { 0 });
        var max = int.Parse(string.Join("", nonZeroDigits.OrderByDescending(i => i)));
        for (int i = 0; i <= max; i++)
        {
            var potential = i;
            var complements = GetComplements(potential, validInput);
            if (complements != null)
            {
                foreach (var complement in complements)
                {
                    var signature = GetSignature(potential, complement);
                    if (!found.Contains(signature))
                    {
                        found.Add(signature);

                        yield return Tuple.Create(potential, complement);
                    }
                }
            }
        }
    }

    private static string GetSignature(int potential, int complement)
    {
        // Sort it so we don't get duplicates.
        var key = new[] { potential, complement }.OrderBy(i => i).ToArray();
        var formatted = string.Format("{0} {1}", key[0], key[1]);
        return formatted;
    }

    private static List<int> GetComplements(int potential, int[] validInput)
    {
        var remaining = validInput.ToList();
        var digits = potential.ToString().Select(c => int.Parse(c.ToString())).ToArray();

        foreach (var d in digits)
        {
            // This means the potential isn't a valid candidate.
            if (!remaining.Contains(d))
            {
                return null;
            }

            remaining.Remove(d);
        }

        // This means there were no other digits to choose.
        if (remaining.Count == 0)
        {
            return null;
        }
        else
        {
            var complements = new List<int>();
            Scramble(complements, "", remaining);
            return complements;
        }
    }

    private static void Scramble(List<int> complements, string result, IEnumerable<int> remaining)
    {
        if (remaining.Any())
        {
            foreach (var i in remaining)
            {
                var childResult = result + i;
                var childRemaining = remaining.Except(new[] { i });

                Scramble(complements, childResult, childRemaining);
            }
        }
        else
        {
            if (!result.StartsWith("0") || result.Length == 1)
            {
                var intResult = int.Parse(result);
                complements.Add(intResult);
            }
        }
    }

    private static int[] ValidateInput(IEnumerable<int> input)
    {
        // Make sure (2) integers were entered.
        if (input == null || input.Count() < 2)
        {
            // TODO
            throw new Exception();
        }

        // Make sure you don't have duplicates.
        var result = input.Distinct().ToArray();

        // Make sure the numbers are in range.
        if (result.Min() < 0 || result.Max() > 9)
        {
            // TODO
            throw new Exception();
        }

        return result;
    }
}

提示函数可以这样内联。

答案 2 :(得分:2)

这是一个带有可选默认提示的版本:

function read_confirm --description 'Ask the user for confirmation' --argument prompt
    if test -z "$prompt"
        set prompt "Continue?"
    end 

    while true
        read -p 'set_color green; echo -n "$prompt [y/N]: "; set_color normal' -l confirm

        switch $confirm
            case Y y 
                return 0
            case '' N n 
                return 1
        end 
    end 
end

答案 3 :(得分:1)

借助一些鱼插件fishermanget

要安装两者,只需在鱼壳中

即可
curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher
. ~/.config/fish/config.fish
fisher get

然后你可以在fish function / script

中写下这样的东西
get --prompt="Are you sure  [yY]?:" --rule="[yY]" | read confirm
switch $confirm
  case Y y
    # DELETE COMMAND GOES HERE
end