3

I know some methods for stopping process. When I type:

echo {1..999999} > filename.txt 

I can't stop it from running. I can stop other processes with Ctrl+C | Ctrl+D | Ctrl+\ and etc. But none of them seem to be working with this command.

Some guys told me to simply close this terminal. Other than that, open new terminal kill all terminal processes, but I don't want to do it this way. In the server I won't have such chance to open new terminal, I think.

Can I open a new terminal session in text-mode?

  • possible duplicate of How to kill both process and subprocess? – jasonwryan Mar 14 '15 at 20:37
  • @jasonwryan, thank you. But terminal is not responding and these methods don't help either. – rzaaeeff Mar 14 '15 at 20:39
  • 1
    Usually you can stop that process with ctrl-z (forgot already how to make that buttons). Or from another shell, kill the shell with -9. – ott-- Mar 14 '15 at 22:18
  • 1
    You can definitely get another terminal going on a server by just ssh'ing into it again. – Bratchley Mar 15 '15 at 2:12
  • @ott--, thank you so much! ctrl+z didn't work either. Killing with PID works well. – rzaaeeff Mar 15 '15 at 8:47
4

The reason why cannot interrupt that with Ctrl-c etc... is that the shell isn't running any command at that point. It's busy expanding {1..999999} to compute what the command line arguments will eventually be once it gets to the point of running the command.

While external commands respond to termination signals like SIGINT (which is emitted by default when you press Ctrl-c), shells themselves ignore them. If they didn't, then, when you pressed Ctrl-c, then in addition to killing whatever command happened to be running, you'd also kill the shell itself! (This is not quite true because of tty job control and foreground and background process groups, but close enough for the purpose of that explanation.)

If you need to interrupt it, there is unfortunately nothing you can do but kill the shell itself. Killing the shell itself will cause your session to terminate. In that sense it's largely equivalent to closing the terminal window or terminating the SSH connection.

  • Thank you so much, @Celada. It helped to understand why i can't stop that ongoing process. – rzaaeeff Mar 15 '15 at 8:52
3

If you want an alternative that can be stopped with ctrl+c, the following works in bash:

i=1; while [ $i -le 999999 ]; do echo $((i++)) >> filename.txt; done

Be sure to use the redirection symbol1 >> to append to the file instead of overwrite it.


Also, I seem to be able to stop it with ctrl+c when running the command within a subshell using parenthesis ( echo {1..999999} > numero.txt ) Note that the output file is never created for the reasons Celada explained.

See Subshells - Advanced Bash-Scripting Guide


To further support Celada's answer, below is the order in which the bash shell's fork-and-exec scheme operates. You can see that the command is not executed until after shell expansions are performed; no fork is yet created. In the command echo {1..999999} > filename.txt, the parent shell is the process in which the shell expansion is being performed. ctrl+c, of course, doesn't kill the parent shell.

From Bash Guide for Beginners 1.4.1.1. Shell syntax

If input is not commented, the shell reads it and divides it into words and operators, employing quoting rules to define the meaning of each character of input. Then these words and operators are translated into commands and other constructs, which return an exit status available for inspection or processing. The above fork-and-exec scheme is only applied after the shell has analyzed input in the following way:

  • The shell reads its input from a file, from a string or from the user's terminal.

  • Input is broken up into words and operators, obeying the quoting rules, see Chapter 3. These tokens are separated by metacharacters. Alias expansion is performed.

  • The shell parses (analyzes and substitutes) the tokens into simple and compound commands.

  • Bash performs various shell expansions, breaking the expanded tokens into lists of filenames and commands and arguments.

  • Redirection is performed if necessary, redirection operators and their operands are removed from the argument list.

  • Commands are executed.

  • Optionally the shell waits for the command to complete and collects its exit status.

From Bash Guide for Beginners 3.4.1. General

After the command has been split into tokens (see Section 1.4.1.1), these tokens or words are expanded or resolved. There are eight kinds of expansion performed, which we will discuss in the next sections, in the order that they are expanded.

Brace expansion is the first among the order of expansions performed.


Stopping a Shell Expansion

You can actually stop a shell expansion by sending kill -SIGSTOP <pid> to the pid of the shell. echo $$ will give the pid of the current shell or you can try pgrep -l bash and try to determine which shell is running the expansion.

The expansion can be resumed where it left off with kill -SIGCONT <pid>.

I don't know of any way to kill the expansion aside from killing the parent shell or letting it finish. To me, this makes a good case for running expansions in a subshell.

  • Thank you so much, @iyrin. I'll choose that route, also i'll upvote your answer as soon as i get enough reputation. – rzaaeeff Mar 15 '15 at 8:53
  • It's strange that we can stop it while using parenthesis. – rzaaeeff Mar 15 '15 at 11:51
  • 1
    The parenthesis run the command in a subshell. It's probably more accurate to say that we are stopping the subshell; not the command. – iyrin Mar 15 '15 at 18:44
  • 1
    Your while loop would be portable (and immune to $IFS) if you properly quoted the expansions and altered the syntax only a little. Like: i=0; while [ "$((i+=1))" -le 1000000 ]; do echo "$i"; done >file. Also note the one redirection - doing the open() for every echo is probably not optimal. Better still would be to save the increment in "$@" and write() incremental blocked occurrences so you also don't have to write() a million times. But seq 1000000 >file does that already. – mikeserv Mar 16 '15 at 3:29
  • @mikeserve - I've created a chat if you'd like to participate. chat.stackexchange.com/rooms/21977/better-increment-loops – iyrin Mar 16 '15 at 5:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.