Stopping Cassandra in Shell script - bash

What shell command would you use to stop Cassandra started locally? Is there one that stops it without the PID? If no, what command can you use to get the PID in shell script?

Please tailor to your individual situation, since you mentioned that C* is started locally.
However you can use something like this in your script:
#!/bin/bash
PID=$(cat /var/run/cassandra/cassandra.pid)
sudo kill -9 $PID

If you started Cassandra without designating a file for the PID, then you'll have to do something tricky, like this:
ps -ef | grep cassandra | grep "jmx\.local\.port=7199" | awk '{print $2}'
96165
Basically you're using ps to get the status of all processes, grepping for "cassandra", and then grepping for something very specific to the Cassandra process (like local JMX on port 7199). Then, if you pipe that all through awk, you can pretty easily just pull the second space-delimited "column."
There's probably a more graceful way to do this, but it'll work.
Then, as a user with privileges to the cassandra process, you can just run a kill on that PID. Or, you could encapsulate that all into one, single command:
kill $(ps -ef | grep cassandra | grep "jmx\.local\.port=7199" | awk '{print $2}')

Stopping a local Cassandra instance depends on the installation type.
If you've installed Cassandra as a YUM (RHEL/CentOS) or APT (Debian) package, stop the service with:
$ sudo service cassandra stop
If you've installed Cassandra using the binary tarball, you can simply kill it with:
$ pkill cassandra
Note that if you're running Cassandra as another user such as root, you'll need to use sudo to get elevated permissions. Cheers!

Related

How to retrieve docker container name from pid of docker exec on the host (MacOS)

I'm trying to find out the name of a docker container given the pid of the docker exec command on the host. host system is MacOS (Catalina, but that shouldn't matter).
This information is available in a script I am writing, but it's the starting point, just as if you would do
localhost $ ps ax | grep docker | grep what-i-am-looking.for
8968 ... docker exec [args...] [optional command]
If I inspect the running containers, the pid is not listed there.
localhost $ docker ps -q | xargs docker inspect | grep 8968
# nothing, so the PID is not stored
There's a different PID however
localhost $ docker ps -q | xargs docker inspect '{{.State.Pid}}'
31093
6836
which has nothing to do with anything running on the host, nor inside docker (pids don't exist).
I can retrieve the Exec-IDs of running containers by
docker ps -q | xargs docker inspect -f '{{.ExecIDs}}'
or a bit more handy to work with
docker ps -q | xargs docker inspect | jq -r '.[0].ExecIDs[] | .'
and get some info about this via
curl --unix-socket /var/run/docker.sock -H 'Content-Type: application/json' http://docker/exec/$EXEC_ID/json
There's also a PID listed (a different one, like 31166), but this number has again nothing to do with the host.
Any idea how to find out which container the command on the host belongs to?
The alternative is to parse the docker exec / run command string, but due to the variety of arguments possible and optional commands that may be given I don't think it's a good idea.
For that I could check each word in the command string against the name found in one of the docker inspect calls, but I think it's too brittle.
BTW: CoreOS - get docker container name by PID? doesn't help since PIDs are different (see text( and there's no /proc on in MacOS.
The approach you're taking won't work on MacOS. Parsing the docker exec command to find the first non-option argument is probably the only way to find this.
On MacOS, there is a hidden Linux VM that actually runs the containers. This means there are three process ID namespaces (the host's, the VM's, and the container's). The other important distinction is that the docker exec process isn't the same process as the process that's running inside the container. So you're trying to match the MacOS host pid of the docker exec process against the Linux VM pid of the main container process, and they'll never match up.
You can get a shell inside the Linux VM (see for example this answer) and then the docker inspect pids will be visible. But now, because of Docker's client-server architecture, there is no docker exec process; it only exists on the MacOS host. You should be able to see the process it launches but it's hard to know that process comes from docker exec.
+------------------------------+
| ................ |
docker exec ... ------> dockerd ---> process : |
(host pid) | (VM pid) : (cont. pid) : |
| ................ |
| Linux VM (VM pid) |
+------------------------------+

Send commands directly in running process and indirectly (e. g. with tail)

I am currently building a docker project for running a Minecraft Spigot server.
To achieve this I need to be able to run commands in the running shell (when using docker run -it d3strukt0r/spigot) and indirectly with docker exec <name> console <command>. Unfortunately, I'm not too fond of the bash language.
Currently, I am able to send commands indirectly, which is great when being detached. I got this with:
_console_input="/app/input.buffer"
# Clear console buffers
true >$_console_input
# Start the main application
echo "[....] Starting Minecraft server..."
tail -f $_console_input | tee /dev/console | $(command -v java) $JAVA_OPTIONS -jar /app/spigot.jar --nogui "$#"
And when running the console command, all it does is the following:
echo "$#" >>/app/input.buffer
The code can be found here
Does someone know a way of how to be able to now add the functionality to directly enter commands?
USE CASE ONE: A user may run attached using docker run
docker run -it --name spigot -p 25565:25565 -e EULA=true d3strukt0r/spigot:nightly
In this case, the user should definitely be able to use the console as he is used to (when running java -jar spigot.jar).
If he has a second console open he can also send a command with:
docker exec spigot console "time set day"
USE CASE TWO: A user may run detached using docker run -d
docker run -d --name spigot -p 25565:25565 -e EULA=true d3strukt0r/spigot:nightly
In this case, the user is only able to send commands indirectly.
docker exec spigot console "time set day"
USE CASE THREE AND FOUR: Use docker-compose (look at the use case "two", it's basically the same)
You could make a script that acts like a mini-shell, reading from stdin and writing to /app/input.buffer. Set it as the container's CMD so it runs by default. Put it in the same directory as your Dockerfile and make sure it's executable.
interactive_console
#!/bin/sh
while IFS= read -rp '$ ' command; do
printf '%s\n' "$command"
done >> /app/input.buffer
Dockerfile
COPY interactive_console /usr/bin
CMD interactive_console

Kill process via sh script called by crontab

i wrote a sh file which kills a tomcat process, suppose my shell scrip is in /usr/temp, script looks likethat:
#!/bin/bash
ps -Af | grep "tomcat_something" | grep -v grep | awk '{print$2}' | xargs sudo kill -9
then i created a cron via crontab -e My cron looks likethat (dont pay attention to the time):
10 10 * * * /usr/temp/myshellscript.sh
If i run the sh without cron it works fine, but via cron is not working at all.
I even tryied to run the same shell script with a touch file command and in this case cron works fine, so my doubt is that the problem is the kill command. Can someone help ?
Problem:
sudo in cron job does not work as it expects a password to be entered.
Possible Solutions
Not Recommended as require to give password in plaintext.
Use expect (Quick google or SO search will help you) in your script
and provide sudo's password there.
Run your script as sudo instead of running sudo inside script
In your own crontab, write your command like so:
10 10 * * * echo "your password" | sudo -S /usr/temp/myshellscript.sh
Again, it is not recommended
Best Possible Way: Use roots crontab (only if you have access)
Run the following command:
sudo crontab -e
This opens up root's crontab. sudo is not necessary to run your command in this context since it'll be invoked as root anyway.

Unable to kill CassandraDaemon

I am using source installation of cassandra. After installation I ran it like this:
$ pwd
/var/users/ec2-user/apache-cassandra-3.10
$ bin/cassandra -f
After this I am getting error:
ERROR [main] 2017-04-04 14:40:34,195 CassandraDaemon.java:752 - Port already in use: 7199; nested exception is:
java.net.BindException: Address already in use (Bind failed)
java.net.BindException: Address already in use (Bind failed)
Then I grep for 7199
$ ps aux | grep 7199
-javaagent:/home/ec2-user/apache-cassandra-3 .10/bin/../lib/jamm-0.3.0.jar -Dcassandra.jmx.local.port=7199
....
org.apache.cassandra.service.CassandraDaemon
Now I am unable to kill CassandraDaemon
kill -9 <process_id_of_CassandraDaemon>
or
pkill -f CassandraDaemon
This is not working. I get 7199 still running .
Please help.
Try one of this at a time:
Try to run these commands with sudo.
sudo service cassandra stop (if you are running on ubuntu).
Restart server :)
7199 is not the process id. It actually a port.
execute this command and find which program already acquired this port.
> netstat -antp | grep 7199
Then use kill command to terminate that program. After then try running cassandra again.
I found the answer by self.
my cassandra was running under supervisord so I had to stop supervisord by running following command
sudo /etc/init.d/supervisord stop
Then I can kill cassandra process.

Using the output of a 'grep search' as the input of a 'yum update' (Shell Script)

I was recommended for this student job by one of my profs. I have never coded a shell script in my life. I have read some tutorials online about shell scripting, but that is it. Anyway, I have been asked to create a script that will run:
find-repos-of-install | grep rpmfusion
and given the output of that search, will run a yum update. Ex:
find-repos-of-install | grep rpmfusion
#that gives this output
libCg-3.1.0013-2.el6.x86_64 from repo rpmfusion-nonfree-updates
pgplot-5.2.2-34.el6.1.x86_64 from repo rpmfusion-nonfree-updates
pgplot-devel-5.2.2-34.el6.1.x86_64 from repo rpmfusion-nonfree-updates
yum update libCg pgplot pgplot-devel
That is what he wants the script to do. I'm not asking anyone to write the whole script for me, just try to point me in the right direction. I've done coding in Java, but that hasn't helped me at all, shell script looks like gibberish to me still. Thanks for any tips/hints
You have two options of how to call a command (yum in your case) with output of another command (grep in your case): one is to do something like:
$ yum update $(find-repos-of-install | grep rpmfusion)
Another one is to use xargs, something like:
$ find-repos-of-install | grep rpmfusion | xargs yum update

Resources