首页 \ 问答 \ 如何在Linux预期的exec命令中执行多个命令(How can I execute more than one command in exec command of linux expect)

如何在Linux预期的exec命令中执行多个命令(How can I execute more than one command in exec command of linux expect)

我试图通过使用Linux的期望来检测主机是否可用。

现在,我可以通过bash使用以下命令来获取返回值并检查主机状态。

#!/usr/bin/bash
nc -z $DUT_IP 22 && echo $?

我想通过期望来做同样的事情。 但似乎我失败了。

#!/usr/bin/expect --   
set DUT_IP "192.168.1.9"
set result [exec nc -z $DUT_IP 22] 
send_user "$result\n\n"

我收到以下错误消息:

    invalid port &&
        while executing
    "exec nc -z $DUT_IP 22 && echo $?"
        invoked from within
    "set result [exec nc -z $DUT_IP 22 && echo $?] "
        (file "reboot.exp" line 44)

I'm trying to detect a host is available by using expect of Linux.

Now, I can using the following commands via bash to get the return value and check host status.

#!/usr/bin/bash
nc -z $DUT_IP 22 && echo $?

I want to do the same things via expect. But seems I failed.

#!/usr/bin/expect --   
set DUT_IP "192.168.1.9"
set result [exec nc -z $DUT_IP 22] 
send_user "$result\n\n"

I got the following error messages:

    invalid port &&
        while executing
    "exec nc -z $DUT_IP 22 && echo $?"
        invoked from within
    "set result [exec nc -z $DUT_IP 22 && echo $?] "
        (file "reboot.exp" line 44)

原文:https://stackoverflow.com/questions/42295776
更新时间:2023-11-02 14:11

最满意答案

这个答案很长,但是我已经用相当多的解释以一种相当容易接近的方式写了它,所以请跟我说一下。

假设AB都是整数,可以在O(N)时间内解决这个问题。 否则你可以在此时停止阅读。 但我认为有必要将算法分解为几个不同的步骤,每个步骤都是O(N) 。 所以它仍然是O(N)整体。

可能问题中最困难的部分是弄清楚如何在线性时间内运行此步骤:

    if ith letter of S is 'R'
        reverse L[i...N]

如果我们只是继续盯着原始算法,我们将确信即使其他步骤可以在线性时间内实现,这个步骤也永远不能在线性时间内完成。 但事实并非如此。 我们该怎么做呢? 我想到的方法是从双端队列/双端队列数据结构中借用一个想法。 由于我们知道数组L有多长,我们只保留3个变量, leftmostrightmostisReversed

  • leftmost将保持L数组当前最左边未使用的索引,因此leftmost的初始化为1 ,因为我们正在使用一个索引数组,如你的问题中所述(术语'未使用'将在后面解释)。
  • rightmost将保持L数组当前最右边未使用的索引,因此初始化为N ,即L的长度。
  • isReversed用于指示阵列是否正在反转。 这被初始化为false

我们的第一个任务是在应用所有reverse操作后计算出数组L的原始元素的最终顺序。 我们甚至不需要反转阵列一次以达到与反转相同的效果。 这可以通过遍历输入串S一次,并且在所有反向操作之后确定阵列L哪个元素应该在每个位置来完成。 为简单起见,我们创建了一个新的整数数组L' ,它将在应用所有反向操作后保存L'的最终原始元素,并尝试填充L'

假设我们在索引i ,并且S[i] == 'R' ,所以我们设置isReversed = true表示我们正在逆转子阵列[i..N] 。 当isReversed == true ,我们知道子阵列[i..N]正在被反转,因此L'[i]处的元素应该是最右边的未使用元素,其索引rightmost 。 因此我们设置L'[i] = L[rightmost] ,并且rightmost 1rightmost = rightmost - 1 )。 相反,如果isReversed == false我们不会反转子[i..N] ,因此L'[i]处的元素应该是最左边的未使用元素,其索引leftmost 。 因此我们设置L'[i] = L[leftmost] ,并且leftmost增加1leftmost = leftmost - 1 )。 后续reverse将否定isReversed的值。

因此,当前的算法在C ++中看起来像这样(我假设您对C ++没问题,因为您的一个问题标签是C ++):

// set up new array L'
int Lprime[N+1];
int leftmost = 1;
int rightmost = N;
bool isReversed = false;

for (int i = 1; i <= N; i++) {
    if (S[i] == 'R') {
        // negate isReversed
        isReversed = !isReversed;
    }

    if (isReversed) {
        Lprime[i] = L[rightmost];
        rightmost = rightmost - 1;
    } else {
        Lprime[i] = L[leftmost];
        leftmost = leftmost + 1;
    }
}

确认这是正确的,尽管我认为是这样。

现在我们来看看原始算法的其余部分:

    else if ith letter of S is 'A'
        add A to all numbers of L[i..N].
    else if ith letter of S is 'M'
        multiply B to all numbers of L[i..N].

    for all number in L[i..N], module them by C.

对于每个索引i ,困难部分似乎需要通过C在子阵列[i..N]上执行模数。 但基于我有限的理解,这是模运算,我们并不需要在每个i子阵列[i..N]上执行它。 但是不要相信我的话。 我对数论的理解非常简陋。

不仅如此,添加和乘法的步骤也可以简化。 这里的技巧是保留2个额外的变量,让我们称它们为multiplicativeFactoradditiveConstantmultiplicativeFactor用于保存我们需要乘以L'[i]的常数。 这最初是1 。 正如其名称所示, additiveConstant变量用于存储我们需要在L'[i]乘以multiplicativeFactor之后添加到L'[i]任何常量。 additiveConstant被初始化为0

为了更具体地看待这一点,让我们设置A = 3B = 5 。 并假设S是字符串"AMMAAM" 。 这意味着以下( 注意:我们现在忽略模C ):

  • 在索引1 ,设置L'[1] = L'[1] + 3;
  • 在索引2 ,设置L'[2] = (L'[2] + 3) * 5;
  • 在索引3 ,设置L'[3] = ((L'[3] + 3) * 5) * 5;
  • 在索引4 ,设置L'[4] = (((L'[4] + 3) * 5) * 5) + 3;
  • 在索引5 ,设置L'[5] = ((((L'[5] + 3) * 5) * 5) + 3) + 3
  • 在索引6 ,设置L'[6] = (((((L'[6] + 3) * 5) * 5) + 3) + 3) * 5

观察到先前字符'A''M' “继承”(或级联)到L'的未来元素中。 让我们稍微改变一下这些操作:

  • L'[1] = L'[1] + 3
  • L'[2] = 5 * L'[2] + (3 * 5)
  • L'[3] = 5 * 5 * L'[3] + (3 * 5 * 5)
  • L'[4] = 5 * 5 * L'[4] + (3 * 5 * 5 + 3)
  • L'[5] = 5 * 5 * L'[5] + (3 * 5 * 5 + 3 + 3)
  • L'[6] = 5 * 5 * 5 * L'[6] + (3 * 5 * 5 + 3 + 3) * 5

我们开始看到一些模式。

  • L'[i]的乘法因子总是B的幂。 添加A对此乘法因子无任何影响。 乘法因子存储在我们上面描述的multiplicativeConstant变量中
  • 每次我们需要将L'[i]乘以一个额外的B ,需要将所有常数(由加A引起)乘以B以获得最终常数以加到L'[i] 。 这是上述additiveConstant变量的目的。
  • L'[i]乘法应该在将additiveConstant加到L'[i]

因此,每个L'[i]的最终值可以表示为multiplicativeConstant * L'[i] + additiveConstant; ,算法的第二个主要部分如下所示:

int multiplicativeConstant = 1;
int additiveConstant = 0;
for (int i = 1; i <= N; i++) {
    if (S[i] == 'A') {
        additiveConstant += A;
    } else if (S[i] == 'M') {
        multiplicativeConstant *= B;
        // need to multiply all the constants by B as well
        additiveConstant *= B;
    }
    Lprime[i] = multiplicativeConstant * Lprime[i] + additiveConstant;
}

有一点需要注意,我没有谈过。 multiplicativeConstantadditiveConstant 整数溢出 ,以及中间计算。 如果L是一个int数组,我们很幸运,因为我们可以使用long long来避免溢出。 否则,我们必须小心中间计算不会溢出。

那么modulo C操作呢? 实际上,他们将L'[i]中的每个值保持在[0..C-1]范围内。 基于我对数论的有限理解,我们可以像这样执行模运算来实现相同的效果:

int multiplicativeConstant = 1;
int additiveConstant = 0;
for (int i = 1; i <= N; i++) {
    if (S[i] == 'A') {
        additiveConstant = (additiveConstant + (A % C)) % C;
    } else if (S[i] == 'M') {
        multiplicativeConstant = (multiplicativeConstant * (B % C)) % C;
        // need to multiply all the constants by B as well
        additiveConstant = (additiveConstant * (B % C)) % C;
    }
    Lprime[i] = ((multiplicativeConstant * (Lprime[i] % C)) % C + additiveConstant) % C;
}

这解决了multiplicativeConstantadditiveConstant变量的溢出问题(但不会阻止中间计算和其他变量的溢出),并完成我们的算法。 我相信这是正确的,但请亲自验证。 我无法解释模块化算术的东西,因为我只知道如何使用它,所以你必须自己查找。 另外, A % CB % C部分可以完成一次,结果存储在变量中。

最后,把所有东西放在一起

// set up new array L'
int Lprime[N+1];
int leftmost = 1;
int rightmost = N;
bool isReversed = false;

for (int i = 1; i <= N; i++) {
    if (S[i] == 'R') {
        // negate isReversed
        isReversed = !isReversed;
    }

    if (isReversed) {
        Lprime[i] = L[rightmost];
        rightmost = rightmost - 1;
    } else {
        Lprime[i] = L[leftmost];
        leftmost = leftmost - 1;
    }
}

int multiplicativeConstant = 1;
int additiveConstant = 0;
// factor out A % C and B % C
int aModC = A % C;
int bModC = B % C;
for (int i = 1; i <= N; i++) {
    if (S[i] == 'A') {
        additiveConstant = (additiveConstant + aModC) % C;
    } else if (S[i] == 'M') {
        multiplicativeConstant = (multiplicativeConstant * bModC) % C;
        // need to multiply all the constants by B as well
        additiveConstant = (additiveConstant * bModC) % C;
    }
    Lprime[i] = ((multiplicativeConstant * (Lprime[i] % C)) % C + additiveConstant) % C;
}
// print Lprime

这总体上在O(N)时间内运行。

再一次,如果你担心整数溢出,假设L是一个int数组,你可以使用long long来计算所涉及的所有变量,你应该没问题。


This answer is quite long, but imho I've written it in a rather accessible manner with quite a bit of explanation, so do bear with me for a moment.

It is possible to solve this in O(N) time, assuming that A and B are both integers. Otherwise you can stop reading at this point. But I think there is a need to break apart the algorithm into several distinct steps, each of which is O(N). So it will still be O(N) overall.

Probably the most difficult part of the problem is to figure out how to make this step run in linear time:

    if ith letter of S is 'R'
        reverse L[i...N]

If we just keep staring at the original algorithm, we will be convinced that even if the other steps can be achieved in linear time, this step can never be done in linear time. But that is not true. How do we do it? The way I thought of is to borrow an idea from the double ended queue / deque data structure. Since we know how long the array L is, we just maintain 3 variables, leftmost, rightmost and isReversed.

  • leftmost will hold the current leftmost unused index of the L array, so leftmost is initialized to 1, since we are using one indexed arrays as stated in your question (the term 'unused' will be explained later).
  • rightmost will hold the current rightmost unused index of the L array, and hence initialized to N, the length of L.
  • isReversed is used to indicate whether the array is being reversed. This is initialized to false.

Our first task at hand is to figure out the final order of the original elements of array L after all the reverse operations have been applied. We do not need to reverse the array even once to achieve the same effect as reversing. This can be done by traversing the input string S once, and figuring out which element of array L should be at each position after all the reverse operations. For simplicity, we create a new integer array L' that will hold the final original elements of L after applying all the reverse operations, and attempt to fill in L'.

Suppose we are at index i, and S[i] == 'R', so we set isReversed = true to indicate that we are reversing subarray [i..N]. When isReversed == true, we know that the subarray [i..N] is being reversed, so the element at L'[i] should the rightmost unused element, whose index is rightmost. Hence we set L'[i] = L[rightmost], and decrement rightmost by 1 (rightmost = rightmost - 1). Conversely, if isReversed == false we are not reversing subarray [i..N], so the element at L'[i] should be the leftmost unused element, whose index is leftmost. Hence we set L'[i] = L[leftmost], and increment leftmost by 1 (leftmost = leftmost - 1). Subsequent reverse will negate the value of isReversed.

So the current algorithm looks like this in C++ (I assume you're ok with C++ since one of your question's tags is C++):

// set up new array L'
int Lprime[N+1];
int leftmost = 1;
int rightmost = N;
bool isReversed = false;

for (int i = 1; i <= N; i++) {
    if (S[i] == 'R') {
        // negate isReversed
        isReversed = !isReversed;
    }

    if (isReversed) {
        Lprime[i] = L[rightmost];
        rightmost = rightmost - 1;
    } else {
        Lprime[i] = L[leftmost];
        leftmost = leftmost + 1;
    }
}

Do verify that this is correct, although I believe it to be so.

Now we look at the rest of the original algorithm:

    else if ith letter of S is 'A'
        add A to all numbers of L[i..N].
    else if ith letter of S is 'M'
        multiply B to all numbers of L[i..N].

    for all number in L[i..N], module them by C.

The hard part seems to be the need to perform a modulo by C on subarray [i..N] for each index i. But based on my limited understanding, this is modulo arithmetic, and we do not really need to perform it on subarray [i..N] for each i. But do not take my word for it. My understanding of number theory is very rudimentary.

Not only that, the steps for the adding and multiplication can be simplified as well. The trick here is to maintain 2 extra variables, let's call them multiplicativeFactor and additiveConstant. multiplicativeFactor is used to hold a constant we need to multiply to L'[i]. This is initially 1. The additiveConstant variable, as its name suggests, is used to store any constant we need to add to L'[i] after the multiplication of L'[i] by multiplicativeFactor is done. additiveConstant is initailized to 0.

To see this in a more concrete way, let's set A = 3, B = 5. And suppose S is the string "AMMAAM". Which means the following (NOTE: we ignore the modulo C for now):

  • At index 1, set L'[1] = L'[1] + 3;
  • At index 2, set L'[2] = (L'[2] + 3) * 5;
  • At index 3, set L'[3] = ((L'[3] + 3) * 5) * 5;
  • At index 4, set L'[4] = (((L'[4] + 3) * 5) * 5) + 3;
  • At index 5, set L'[5] = ((((L'[5] + 3) * 5) * 5) + 3) + 3
  • At index 6, set L'[6] = (((((L'[6] + 3) * 5) * 5) + 3) + 3) * 5

Observe that the effect of prior characters 'A' and 'M' "carry over" (or cascade) into the future elements of L'. Let's express these operations slightly differently:

  • L'[1] = L'[1] + 3
  • L'[2] = 5 * L'[2] + (3 * 5)
  • L'[3] = 5 * 5 * L'[3] + (3 * 5 * 5)
  • L'[4] = 5 * 5 * L'[4] + (3 * 5 * 5 + 3)
  • L'[5] = 5 * 5 * L'[5] + (3 * 5 * 5 + 3 + 3)
  • L'[6] = 5 * 5 * 5 * L'[6] + (3 * 5 * 5 + 3 + 3) * 5

We start to see some patterns.

  • The multiplicative factor of L'[i] is always a power of B. Adding of A has no effect whatsoever on this multiplicative factor. The multiplicative factor is stored in the multiplicativeConstant variable we described above
  • Each time we need to multiply L'[i] by an additional B, there is a need to multiply all the constants (incurred from adding A) by B to obtain the final constant to add to L'[i]. This is the purpose of the additiveConstant variable described above.
  • Multiplication of L'[i] should be done before addition of the additiveConstant to L'[i]

Hence, the final value of each L'[i] can be expressed as multiplicativeConstant * L'[i] + additiveConstant;, and the second main portion of the algorithm looks like this:

int multiplicativeConstant = 1;
int additiveConstant = 0;
for (int i = 1; i <= N; i++) {
    if (S[i] == 'A') {
        additiveConstant += A;
    } else if (S[i] == 'M') {
        multiplicativeConstant *= B;
        // need to multiply all the constants by B as well
        additiveConstant *= B;
    }
    Lprime[i] = multiplicativeConstant * Lprime[i] + additiveConstant;
}

There is one caveat that I've not talked about. Integer overflow of multiplicativeConstant and additiveConstant, along with intermediate calculations. If L is an int array, we are in luck, since we can use long long for everything and avoid the overflow. Otherwise, we have to be careful that intermediate computations do not overflow.

Now what about the modulo C operations? In actual fact, they are there to keep every value in L'[i] within the range [0..C-1]. Based on my limited understanding of number theory, we can perform modulo arithmetic like this to achieve the same effect:

int multiplicativeConstant = 1;
int additiveConstant = 0;
for (int i = 1; i <= N; i++) {
    if (S[i] == 'A') {
        additiveConstant = (additiveConstant + (A % C)) % C;
    } else if (S[i] == 'M') {
        multiplicativeConstant = (multiplicativeConstant * (B % C)) % C;
        // need to multiply all the constants by B as well
        additiveConstant = (additiveConstant * (B % C)) % C;
    }
    Lprime[i] = ((multiplicativeConstant * (Lprime[i] % C)) % C + additiveConstant) % C;
}

This addresses the overflow issue of the multiplicativeConstant and additiveConstant variables (but does not prevent overflow of intermediate computations and other variables), and completes our algorithm. I believe this is correct, but do verify it for yourself. I am unable to explain the modular arithmetic stuff since I only know how to use it, so you will have to look it up by yourself. On a side note, the A % C and B % C parts can be done once with their results stored in variables.

Finally, putting everything together:

// set up new array L'
int Lprime[N+1];
int leftmost = 1;
int rightmost = N;
bool isReversed = false;

for (int i = 1; i <= N; i++) {
    if (S[i] == 'R') {
        // negate isReversed
        isReversed = !isReversed;
    }

    if (isReversed) {
        Lprime[i] = L[rightmost];
        rightmost = rightmost - 1;
    } else {
        Lprime[i] = L[leftmost];
        leftmost = leftmost - 1;
    }
}

int multiplicativeConstant = 1;
int additiveConstant = 0;
// factor out A % C and B % C
int aModC = A % C;
int bModC = B % C;
for (int i = 1; i <= N; i++) {
    if (S[i] == 'A') {
        additiveConstant = (additiveConstant + aModC) % C;
    } else if (S[i] == 'M') {
        multiplicativeConstant = (multiplicativeConstant * bModC) % C;
        // need to multiply all the constants by B as well
        additiveConstant = (additiveConstant * bModC) % C;
    }
    Lprime[i] = ((multiplicativeConstant * (Lprime[i] % C)) % C + additiveConstant) % C;
}
// print Lprime

This runs in O(N) time overall.

Once again, if you are worried about integer overflow, assuming that L is an int array, you can use long long for all the variables involved in computation, and you should be fine.

相关问答

更多

相关文章

更多

最新问答

更多
  • sp_updatestats是否导致SQL Server 2005中无法访问表?(Does sp_updatestats cause tables to be inaccessible in SQL Server 2005?)
  • 如何创建一个可以与持续运行的服务交互的CLI,类似于MySQL的shell?(How to create a CLI that can interact with a continuously running service, similar to MySQL's shell?)
  • AESGCM解密失败的MAC(AESGCM decryption failing with MAC)
  • Zurb Foundation 4 - 嵌套网格对齐问题(Zurb Foundation 4 - Nested grid alignment issues)
  • 湖北京山哪里有修平板计算机的
  • SimplePie问题(SimplePie Problem)
  • 在不同的任务中,我们可以同时使用多少“上下文”?(How many 'context' we can use at a time simultaneously in different tasks?)
  • HTML / Javascript:从子目录启用文件夹访问(HTML/Javascript: Enabling folder access from a subdirectory)
  • 为什么我会收到链接错误?(Why do I get a linker error?)
  • 如何正确定义析构函数(How to properly define destructor)
  • 垂直切换菜单打开第3级父级。(Vertical toggle menu 3rd level parent stay opened. jQuery)
  • 类型不匹配 - JavaScript(Type mismatch - JavaScript)
  • 为什么当我将模型传递给我的.Net MVC 4控制器操作时,它坚持在部分更新中使用它?(Why is it that when I pass a Model to my .Net MVC 4 Controller Action it insists on using it in the Partial Update?)
  • 在使用熊猫和statsmodels时拉取变量名称(Pulling variable names when using pandas and statsmodels)
  • 如何开启mysql计划事件
  • 检查数组的总和是否大于最大数,反之亦然javascript(checking if sum of array is greater than max number and vice versa javascript)
  • 使用OpenGL ES绘制轮廓(Drawing Outline with OpenGL ES)
  • java日历格式(java Calendar format)
  • Python PANDAS:将pandas / numpy转换为dask数据框/数组(Python PANDAS: Converting from pandas/numpy to dask dataframe/array)
  • 如何搜索附加在elasticsearch索引中的文档的内容(How to search a content of a document attached in elasticsearch index)
  • LinQ to Entities:做相反的查询(LinQ to Entities: Doing the opposite query)
  • 从ExtJs 4.1商店中删除记录时会触发哪些事件(Which events get fired when a record is removed from ExtJs 4.1 store)
  • 运行javascript后如何截取网页截图[关闭](How to take screenshot of a webpage after running javascript [closed])
  • 如何使用GlassFish打印完整的堆栈跟踪?(How can I print the full stack trace with GlassFish?)
  • 如何获取某个exe应用程序的出站HTTP请求?(how to get the outbound HTTP request of a certain exe application?)
  • 嗨,Android重叠背景片段和膨胀异常(Hi, Android overlapping background fragment and inflate exception)
  • Assimp详细说明typedef(Assimp elaborated type refers to typedef)
  • 初始化继承类中不同对象的列表(initialize list of different objects in inherited class)
  • 使用jquery ajax在gridview行中保存星级评分(Save star rating in a gridview row using jquery ajax)
  • Geoxml3 groundOverlay zIndex(Geoxml3 groundOverlay zIndex)