如何在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
最满意答案
这个答案很长,但是我已经用相当多的解释以一种相当容易接近的方式写了它,所以请跟我说一下。
假设
A
和B
都是整数,可以在O(N)
时间内解决这个问题。 否则你可以在此时停止阅读。 但我认为有必要将算法分解为几个不同的步骤,每个步骤都是O(N)
。 所以它仍然是O(N)
整体。可能问题中最困难的部分是弄清楚如何在线性时间内运行此步骤:
if ith letter of S is 'R' reverse L[i...N]
如果我们只是继续盯着原始算法,我们将确信即使其他步骤可以在线性时间内实现,这个步骤也永远不能在线性时间内完成。 但事实并非如此。 我们该怎么做呢? 我想到的方法是从双端队列/双端队列数据结构中借用一个想法。 由于我们知道数组
L
有多长,我们只保留3个变量,leftmost
,rightmost
和isReversed
。
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
减1
(rightmost = rightmost - 1
)。 相反,如果isReversed == false
我们不会反转子[i..N]
,因此L'[i]
处的元素应该是最左边的未使用元素,其索引leftmost
。 因此我们设置L'[i] = L[leftmost]
,并且leftmost
增加1
(leftmost = 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个额外的变量,让我们称它们为
multiplicativeFactor
和additiveConstant
。multiplicativeFactor
用于保存我们需要乘以L'[i]
的常数。 这最初是1
。 正如其名称所示,additiveConstant
变量用于存储我们需要在L'[i]
乘以multiplicativeFactor之后添加到L'[i]
任何常量。additiveConstant
被初始化为0
。为了更具体地看待这一点,让我们设置
A = 3
,B = 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; }
有一点需要注意,我没有谈过。
multiplicativeConstant
和additiveConstant
整数溢出 ,以及中间计算。 如果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; }
这解决了
multiplicativeConstant
和additiveConstant
变量的溢出问题(但不会阻止中间计算和其他变量的溢出),并完成我们的算法。 我相信这是正确的,但请亲自验证。 我无法解释模块化算术的东西,因为我只知道如何使用它,所以你必须自己查找。 另外,A % C
和B % 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 thatA
andB
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 isO(N)
. So it will still beO(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
andisReversed
.
leftmost
will hold the current leftmost unused index of theL
array, soleftmost
is initialized to1
, 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 theL
array, and hence initialized toN
, the length ofL
.isReversed
is used to indicate whether the array is being reversed. This is initialized tofalse
.Our first task at hand is to figure out the final order of the original elements of array
L
after all thereverse
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 stringS
once, and figuring out which element of arrayL
should be at each position after all the reverse operations. For simplicity, we create a new integer arrayL'
that will hold the final original elements ofL
after applying all the reverse operations, and attempt to fill inL'
.Suppose we are at index
i
, andS[i] == 'R'
, so we setisReversed = true
to indicate that we are reversing subarray[i..N]
. WhenisReversed == true
, we know that the subarray[i..N]
is being reversed, so the element atL'[i]
should the rightmost unused element, whose index isrightmost
. Hence we setL'[i] = L[rightmost]
, and decrementrightmost
by1
(rightmost = rightmost - 1
). Conversely, ifisReversed == false
we are not reversing subarray[i..N]
, so the element atL'[i]
should be the leftmost unused element, whose index isleftmost
. Hence we setL'[i] = L[leftmost]
, and incrementleftmost
by1
(leftmost = leftmost - 1
). Subsequentreverse
will negate the value ofisReversed
.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 indexi
. But based on my limited understanding, this is modulo arithmetic, and we do not really need to perform it on subarray[i..N]
for eachi
. 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
andadditiveConstant
.multiplicativeFactor
is used to hold a constant we need to multiply toL'[i]
. This is initially1
. TheadditiveConstant
variable, as its name suggests, is used to store any constant we need to add toL'[i]
after the multiplication ofL'[i]
bymultiplicativeFactor
is done.additiveConstant
is initailized to0
.To see this in a more concrete way, let's set
A = 3
,B = 5
. And supposeS
is the string"AMMAAM"
. Which means the following (NOTE: we ignore the moduloC
for now):
- At index
1
, setL'[1] = L'[1] + 3;
- At index
2
, setL'[2] = (L'[2] + 3) * 5;
- At index
3
, setL'[3] = ((L'[3] + 3) * 5) * 5;
- At index
4
, setL'[4] = (((L'[4] + 3) * 5) * 5) + 3;
- At index
5
, setL'[5] = ((((L'[5] + 3) * 5) * 5) + 3) + 3
- At index
6
, setL'[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 ofL'
. 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 ofB
. Adding ofA
has no effect whatsoever on this multiplicative factor. The multiplicative factor is stored in themultiplicativeConstant
variable we described above- Each time we need to multiply
L'[i]
by an additionalB
, there is a need to multiply all the constants (incurred from addingA
) byB
to obtain the final constant to add toL'[i]
. This is the purpose of theadditiveConstant
variable described above.- Multiplication of
L'[i]
should be done before addition of theadditiveConstant
toL'[i]
Hence, the final value of each
L'[i]
can be expressed asmultiplicativeConstant * 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
andadditiveConstant
, along with intermediate calculations. IfL
is anint
array, we are in luck, since we can uselong 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 inL'[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
andadditiveConstant
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, theA % C
andB % 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 anint
array, you can uselong long
for all the variables involved in computation, and you should be fine.
相关问答
更多-
您可以使用二进制搜索的概念来查找起始和结束索引: 要查找起始索引,请将数组减半,如果该值等于或大于输入数字 ,则使用数组的下半部分重复,否则重复上半部分。 当你到达一个大小为1的数组时停止。 要查找起始索引,请将数组减半,如果该值大于输入数字 ,则使用数组的下半部分重复,否则重复上半部分。 当你到达一个大小为1的数组时停止。 请注意,当我们到达一个大小为1的数组时,我们可能是输入数字旁边的一个单元格,所以我们检查它是否等于输入数字,如果不是,我们通过在我们找到的索引中添加/减少1来修复索引。 findSta ...
-
我们有原来的数组int A[N]; 创建第二个数组bool B[N] ,类型为bool=false 。 迭代第一个数组并设置B[A[i]]=true如果为false,否则bing! We have the original array int A[N]; Create a second array bool B[N] too, of type bool=false. Iterate the first array and set B[A[i]]=true if was false, else bing!
-
如果您可以提取并保留任何键以进行进一步比较,那么Boyer-Moore多数投票算法就是您的朋友。 If you can extract and hold any key for further comparisons, then the Boyer-Moore Majority Vote Algorithm is your friend.
-
它不能以线性方式完成,数组未排序,因此您需要在最坏的情况下读取所有元素。 这种直觉非常通用,并且适用于处理未排序数组的许多算法,因为你的重复元素可以等待你的“绑定”。 当然,同样的直觉不适用于排序数组的问题。 It cannot be done sub-linearly, the array is unsorted, so you need to read all elements at worst case. This intuition is pretty generic and holds for m ...
-
你可以在O(N + M)时间和O(N)空间中这样做: 将数组a元素放入哈希集中 遍历数组b ,检查哈希表是否包含2-b[i] 构造N元素的散列集需要O(N)时间和O(N)空间。 针对散列集检查M元素中的每一个取O(1),总共O(N + M)个时间。 You can do it in O(N+M) time and O(N) space like this: Put elements of array a into a hash set Walk through array b, and check if h ...
-
可以单独考虑左侧最近上升器和右侧最近上升器。 我们经历了一次数组,计算出最接近的上升点; 并再一次在相反的方向,计算最近的上升。 最近的上升者是两者中最接近的。 在下面的算法中,只考虑左上方。 一堆索引跟踪当前元素的左上升(所有这些)。 最近的上升器始终位于堆栈的顶部。 for i in 0 .. N while (!stack.empty) && (A[stack.top] <= A[i]) stack.pop if stack.empty then R[i] = 0 el ...
-
这个答案很长,但是我已经用相当多的解释以一种相当容易接近的方式写了它,所以请跟我说一下。 假设A和B都是整数,可以在O(N)时间内解决这个问题。 否则你可以在此时停止阅读。 但我认为有必要将算法分解为几个不同的步骤,每个步骤都是O(N) 。 所以它仍然是O(N)整体。 可能问题中最困难的部分是弄清楚如何在线性时间内运行此步骤: if ith letter of S is 'R' reverse L[i...N] 如果我们只是继续盯着原始算法,我们将确信即使其他步骤可以在线性时间内实 ...
-
对数组进行排序,遍历数组字段,与每个步骤增加的计数器进行比较,如果i与向量中的字段push_back(i)不同。 Sort your array, iterate over the array fields, compare to a counter i you increment at every step, if i is different from the field push_back(i) in a vector.
-
我想你想用错误的方法解决这个问题。 我想你想要改进整个算法,而不是O(n)反转的东西。 因为那是不可能的。 如果你必须考虑n个元素中的每一个,你总是有O(n)。 正如我所说,你可以做的是改进O(n ^ 2)算法。 你可以在O(n)中解决这个问题:假设我们有这个列表: a b c d e 然后使用您的算法修改此列表: e d c b a e a b c d 等等..最后你有这个: e a d b c 如果有两个指针来自数组的两端并在指针之间交替(增量/减量/获取值),则可以获取此列表。 这给了你整个程序 ...
-
想象一下,在Base-n系统中表示A[i]中的值。 然后每个数字变成一个五位数的n元数,这意味着您可以使用Radix Sort的五个应用程序对整个数组进行排序 ,其中“radix”为n。 计算数字k中每个“数字”x的值,如下所示: d x =(k /(n x ))%n 其中/表示整数除法。 Imagine representing the values in A[i] in Base-n system. Then each number becomes a five-digit n-ary number, ...