Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cancel current execution after of a new event #93

Closed
emilgpa opened this issue Aug 31, 2015 · 10 comments
Closed

cancel current execution after of a new event #93

emilgpa opened this issue Aug 31, 2015 · 10 comments

Comments

@emilgpa
Copy link

emilgpa commented Aug 31, 2015

I have the following script:

fswatch ts |
while read; do
    echo "changes received";

    echo "compiling typescript files..";
    tsc -p ts/; 

    echo "compiling files with babel...";
    babel ES6 -d scripts --babelrc ES6/babelconfig.json;

    echo "OK";
done

the execution inside of while take 15 seconds, I want that when a new event is raised cancel the current execution and execute it again. How can I do? I know really little about shell script...

@seaside98
Copy link

@DasHaus I created something very similar for a project I'm working on. Basically, you find the PID of the running script and kill it. You may need to change the "fswatch"...

# Find the PIDs
pids=$(ps -ef | grep "fswatch" | grep -v grep | awk '{print $2}')

# Kill them
if [ -n "$pids" ]; then
    kill -9 $pids
fi

# ...

@emilgpa
Copy link
Author

emilgpa commented Sep 20, 2015

And How I can detect when a new event is raised?. Thanks you very much!

@seaside98
Copy link

@DasHaus You will just put that at the beginning of your current script. If any fswatch's are running, they will be stopped, and then yours will be started.

@seaside98
Copy link

@DasHaus Oh, wait. I see what you mean. It will look something like:

fswatch.bash --

fswatch ts |
while read; do

    # Find the PIDs
    pids=$(ps -ef | grep -E "babel|tsc" | grep -v grep | awk '{print $2}')

    # Kill them
    if [ -n "$pids" ]; then
        kill -9 $pids
    fi

    #Start compiling
   ./compile.bash

done

compile.bash --

echo "changes received";

echo "compiling typescript files..";
tsc -p ts/; 

echo "compiling files with babel...";
babel ES6 -d scripts --babelrc ES6/babelconfig.json;

echo "OK";

@emilgpa
Copy link
Author

emilgpa commented Sep 20, 2015

thanks, then I have this in this moment:

compile(){
    p "compiling typescript files.." &&
    tsc -p ts/ &&

    p "transpiling files with babel..." &&
    babel -q ES6 -d scripts --babelrc ts/babelconfig.json &&

    p "OK";
    p "waiting for new changes...";
}

compile;

fswatch ts |
while read; do
    # Find the PIDs
    pids=$(ps -ef | grep -E "babel|tsc" | grep -v grep | awk '{print $2}')

    # Kill them
    if [ -n "$pids" ]; then
        kill -9 $pids
    fi

    p "changes received";
    compile;
done

And don't works... The problem is that the block inside of while It is not executed until the previous iteration ends...

@emilgpa
Copy link
Author

emilgpa commented Sep 20, 2015

The new event is executed when the previous event ends. I don't know if is possible read the events queue in fswatch

@emcrisostomo
Copy link
Owner

That's expected: compile will have to finish before the next while iteration is executed. Use:

compile.sh &

or

nohup compile.sh &

instead.

@emilgpa
Copy link
Author

emilgpa commented Sep 21, 2015

Aaaah, ok!. I understand now. The & is the key. Finally, I can do it in one file:

p(){
    now="$(date +'%r')"
    printf "$(tput setaf 1)%s$(tput sgr0) | $(tput bold)$1$(tput sgr0)\n" "$now";
}

compile(){
    p "compiling typescript files.." &&
    tsc -p ts/ &&

    p "transpiling files with babel..." &&
    babel -q ES6 -d scripts --babelrc ts/babelconfig.json &&

    p "OK!" &&
    p "waiting for new changes...";
}

compile &

fswatch ts |
while read; do
    p "new changes received!"

    # Find the PIDs
    pids=$(ps -ef | grep -E "babel|tsc" | grep -v grep | awk '{print $2}')

    # Kill them
    if [ -n "$pids" ]; then
        p "cancelling actual event..."; kill -9 $pids &> /dev/null
    fi

    compile &
done

It works like a charm! Thanks you both! 👍

@emilgpa emilgpa closed this as completed Sep 21, 2015
@emcrisostomo
Copy link
Owner

You're welcome.

I suggested you using a separate script for the compilation job so that it would be easier to isolate its PID and kill it (and its child processes).

I'm glad you've found a working solution.

@AntoinePrv
Copy link

AntoinePrv commented May 8, 2020

Hi,
For anyone finding this issue, I've made a minimally reproducible example that also make it easier to track the pid. Feedback is welcome :)

long_command(){
	clear
	printf "Starting"
	sleep 1
	printf "."
	sleep 1
	printf "."
	sleep 1
	printf "."
	sleep 1
	printf " done!\n"
}

cancel_and_run() {
	while read; do
		if [ ${command_pid:-0} -gt 0 ]; then
			# Loop until process is effectively killed (synchronous)
			while pkill -P $command_pid 2>/dev/null; do sleep 0.5 ; done
		fi

		( long_command ) &
		local command_pid=$!
	done
}

fswatch somefile | cancel_and_run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants