In the operation and maintenance of AnQi CMS, we often encounter situations where we need to start or stop services.For the AnQiCMS project developed based on the Go language, it usually runs with a single binary executable file.stop.shScript plays a core role. Instop.shIn the script, getting the PID (Process ID) of the running AnQiCMS process is a crucial step, andgrepFollowing closelyawk '{printf $2}'The combination is carefully designed for this purpose.

The starting point for obtaining process information:ps -ef

To understand this combination, we first need to start from:ps -efLet's talk about the command.ps(process status)is a command used in Linux/Unix systems to report the current process status. When combined-efWhen selecting an option, it will display detailed information about all running processes, including the user, PID, parent process PID, CPU usage, startup time, and the complete command path.

ps -efThe output of the command is usually like this:

UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jan01 ?        00:00:10 /sbin/init
user     12345     1  0 10:00 ?        00:00:05 /path/to/anqicms
user     12346 12345  0 10:00 ?        00:00:01 /path/to/anqicms --child-process
user     20000 19999  0 11:30 pts/0    00:00:00 grep --color=auto anqicms

Among which, the second column (PID) is the process ID we are looking for.

Precise filtering:grep '\<anqicms\>' | grep -v grep

Using onlyps -efThis will list all processes, and we need to filter out the processes related to AnQiCMS. At this time,grepthe command comes into play.

  1. grep '\<anqicms\>':

    • grepUsed to search for a specified pattern in text. Here, it is used to find lines containing the string 'anqicms'.
    • \<and\>It is a word boundary marker in regular expressions. This meansgrepWill exactly match 'anqicms' as a whole word, not as a substring like 'myanqicms' or 'anqicms_test'.This ensures that we only match the AnQiCMS main program and not other unrelated processes that may contain “anqicms”.
    • This step will output the process reduced to only contain.anqicmsThe line.
  2. grep -v grep:

    • grep -vThe function is to reverse match, that is, exclude lines containing the specified pattern.
    • When we use in the pipeline.ps -ef | grep anqicmswhengrep anqicmsThis command itself will become a running process, and its command string naturally contains 'anqicms'. If not distinguished,grepThe PID of the command itself is also returned, which is not the result we want.
    • grep -v grepThe function is to removegrepCommanding the process information of itself, ensuring that the PID we obtain only belongs to AnQiCMS service.

After these twogrepThe filter will produce clean output, containing only the full lines of the AnQiCMS service process (if it is running).

Extract core:awk '{printf $2}'

Now we have obtained the lines that only contain AnQiCMS process information, the next step is to accurately extract the PID from these lines.awk(Aho, Weinberger, and Kernighan) is a powerful text processing tool, it is very suitable for this column-based data extraction.

  1. awk '{...}':awkDefault to space or tab as field separators, and parse each line into multiple fields, using$1,$2,$3to indicate.
  2. $2: Inps -efIn the output, the process ID (PID) is located in the second column. Therefore,$2Exactly represents the PID we need.
  3. printf $2:
    • printfYesawkof a function, similar to C language'sprintfused for formatting output.
    • Withprint $2different,printf $2after printing.$2the value of.Will not automatically add a newline character.
    • In shell scripts, when we want to assign the output of a command to a variable, we usually expect the output to be a single-line string without any extra newline characters. If we useprint $2,existsThe variable may capture a newline character following the PID, which may cause issues in subsequent commands (thoughkillcommands may cause issues althoughkillIt can usually handle trailing newline characters). What's more important is that if there are multiple AnQiCMS processes (although for Go applications it is usually a single main process),printf $2This will match all found PIDsconcatenateinto a long string (for example,1234567890), which is executedkill -9 $existswhenkillThe command attempts to kill a non-existent PID instead of all matching PIDs. However, for scenarios like AnQiCMS which usually runs a single main Go process,printf $2The expected behavior is to return a unique PID and assign it as a single string toexiststhe variable, forkillcommand use. When no matching process is found,awkno content will be output,existsThe variable will be empty, thus being interpreted as 0 by Shell.if [ $exists -eq 0 ]in the context of,

The advantages of this combination are

  • accuracy: Throughgrepword boundary matching andgrep -vThe exclusion of self ensures that only the target AnQiCMS process is focused.
  • Robustness:awkin processingpsWhen outputting, it is more flexible than simplecutcommands becausepsThe column width and delimiter may vary slightly due to system or parameter differences, butawkthe field recognition capability is usually more stable.
  • simple and efficientThis pipeline command chain simply implements the function of locating and extracting a specific PID from a large amount of process information, suitable for script automation tasks.
  • Friendly to variables:awkCombineprintfAvoided extra newline characters, making the output directly usable for shell variable assignment, convenient for subsequent operationskillOperation.

In short, AnQiCMSstop.shthe script ingrepafter useawk '{printf $2}'The combination is to locate the PID of the AnQiCMS main process in a complex process list in an accurate, robust, and efficient manner, and extract it into a clean string, so that it can be passed throughkillCommand to terminate.


Common Questions and Answers (FAQ)

1. Why not usepkill anqicmsTo stop the process?

pkillThe command indeed provides a more concise way to terminate processes by name. However, its behavior and default match patterns may vary slightly across different systems. For example, ifpkillBy default, substring matching is performed, so any process (such as a test script or log file processor) containing 'anqicms' may be mistakenly terminated.ps -ef | grep ... | awk ...This chained command provides a finer, more transparent control flow, allowing operators to precisely define matching rules (such as\<anqicms\>Ensure word boundary matching) to reduce the risk of false positives. In production environments that require high stability and controllability, this explicit layer-by-layer filtering method is sometimes more preferred.pkillMore favored.

2. If multiple processes namedanqicmsare running in the systemstop.shhow should it be handled?

Instop.shin the existing implementation of the scriptawk '{printf $2}'will be the PIDs of all matching processesconcatenateBecome a long string without spaces or separators. For example, if the PID is12345and67890,existsThe variable will become"1234567890". When the script is executedkill -9 $existswhenkillThe command will try to terminate1234567890This PID, and this number composed of multiple PID concatenations usually does not correspond to any running process. This means that the script will not be able to correctly terminate all matchinganqicmsProcess. For applications like AnQiCMS that are written in Go, it is typically expected to run only one main process. If multiple processes do exist,anqicmsProcess, this usually indicates an exceptional condition or deployment error. A more robust approach is to use a loop (for examplefor pid in $(ps -ef | grep ... | awk '{print $2}'); do kill -9 $pid; done) to terminate each matching PID one by one.

3.awkIs the method of extracting PID more recommended than other tools (such ascut)?

Yes, in extracting specific columns fromps -efsuch command outputs,awkusuallycutit is more recommended.cutBased on fixed position or a single delimiter for cropping,psthe output format may have a variable number of spaces as delimiters, resulting in non-fixed column positions.awkDefault to any number of whitespace characters as field separators, which makes it more flexible and robust when outputting, less likely to fail due to minor format changes.psTherefore, it is more flexible and robust when outputting, less likely to fail due to minor format changes.awk '{printf $2}'It is a general and reliable choice.