-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
365 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
lodings.. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
loding.. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/** | ||
* Pipe 管道学习 | ||
* | ||
* @author ShaoWei Pu <marco0727@gamil.com> | ||
* @date 2017/10/9 | ||
* ------------------------------------------------------------- | ||
* 0x01. exec包执行外部命令,它将os.StartProcess进行包装使得它更容易映射到stdin和stdout,并且利用pipe连接i/o. | ||
* 0x02. 命名管道可以被多路复用 | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"os/exec" | ||
"fmt" | ||
"Go-example/Debug" | ||
"bytes" | ||
"time" | ||
"io" | ||
"os" | ||
) | ||
|
||
// output echo | ||
func SimpleEcho() { | ||
cmd := exec.Command("echo", "-n", "I'm Echo") | ||
if err := cmd.Start(); err != nil { | ||
Debug.ErrorMsg(err) | ||
return | ||
} | ||
stdout, err := cmd.StdoutPipe() | ||
if err != nil { | ||
Debug.ErrorMsg(err) | ||
return | ||
} | ||
// 保证关闭输出流 | ||
defer stdout.Close() | ||
output := make([]byte, 30) | ||
n, err := stdout.Read(output) | ||
if err != nil { | ||
Debug.ErrorMsg(err) | ||
return | ||
} | ||
fmt.Printf("%s\n", output[:n]) | ||
} | ||
|
||
// output pipe | ||
func anonymousPipe() { | ||
cmdLeft := exec.Command("ps", "aux") | ||
cmdRight := exec.Command("grep", "php") | ||
var outputBuf bytes.Buffer | ||
cmdLeft.Stdout = &outputBuf // stdout | ||
if err := cmdLeft.Start(); err != nil { | ||
Debug.ErrorMsg(err) | ||
return | ||
} | ||
if err := cmdLeft.Wait(); err != nil { | ||
Debug.ErrorMsg(err) | ||
return | ||
} | ||
cmdRight.Stdin = &outputBuf // stdin | ||
var outputBufRight bytes.Buffer | ||
cmdRight.Stdout = &outputBufRight | ||
if err := cmdRight.Start(); err != nil { | ||
Debug.ErrorMsg(err) | ||
return | ||
} | ||
if err := cmdRight.Wait(); err != nil { | ||
Debug.ErrorMsg(err) | ||
return | ||
} | ||
fmt.Printf("%s \n", outputBufRight.Bytes()) | ||
} | ||
|
||
// 原子操作 | ||
func fileBasedPipe() { | ||
reader, writer, err := os.Pipe() | ||
if err != nil { | ||
fmt.Printf("Error: Couldn't create the named pipe: %s\n", err) | ||
} | ||
go func() { | ||
output := make([]byte, 100) | ||
n, err := reader.Read(output) | ||
if err != nil { | ||
fmt.Printf("Error: Couldn't read data from the named pipe: %s\n", err) | ||
} | ||
fmt.Printf("Read %d byte(s). [file-based pipe]\n", n) | ||
}() | ||
input := make([]byte, 26) | ||
for i := 0; i < 26; i++ { | ||
input[i] = byte(i) | ||
} | ||
n, err := writer.Write(input) | ||
if err != nil { | ||
fmt.Printf("Error: Couldn't write data to the named pipe: %s\n", err) | ||
} | ||
fmt.Printf("Written %d byte(s). [file-based pipe]\n", n) | ||
time.Sleep(200 * time.Millisecond) | ||
} | ||
|
||
func inMemorySyncPipe() { | ||
reader, writer := io.Pipe() | ||
go func() { | ||
output := make([]byte, 100) | ||
n, err := reader.Read(output) | ||
if err != nil { | ||
fmt.Printf("Error: Couldn't read data from the named pipe: %s\n", err) | ||
} | ||
fmt.Printf("Read %d byte(s). [in-memory pipe]\n", n) | ||
}() | ||
input := make([]byte, 26) | ||
for i := 65; i <= 90; i++ { | ||
input[i-65] = byte(i) | ||
} | ||
n, err := writer.Write(input) | ||
if err != nil { | ||
fmt.Printf("Error: Couldn't write data to the named pipe: %s\n", err) | ||
} | ||
fmt.Printf("Written %d byte(s). [in-memory pipe]\n", n) | ||
time.Sleep(200 * time.Millisecond) | ||
} | ||
|
||
func main() { | ||
// SimpleEcho() // 通过调用Linux命令输出Echo // Ps: 妈的 第一个Demo 就不是想象中的样子 exec: StdoutPipe after process started | ||
// anonymousPipe() // ps aux | grep php << 这个好使 | ||
fileBasedPipe() | ||
inMemorySyncPipe() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
/** | ||
* Signal 信号 | ||
* | ||
* @author ShaoWei Pu <marco0727@gamil.com> | ||
* @date 2017/10/9 | ||
* ------------------------------------------------------------- | ||
* 0x01. `kill -l` | ||
* - 标准信号: 1 - 31 | ||
* - 实时信号:34 - 63 | ||
* 0x02. 这章看起来太枯燥,等后面弄完在来温习 | ||
*/ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"os" | ||
"os/exec" | ||
"os/signal" | ||
"runtime/debug" | ||
"strconv" | ||
"strings" | ||
"sync" | ||
"syscall" | ||
"time" | ||
) | ||
|
||
func main() { | ||
//simpleSignal() | ||
go func() { | ||
time.Sleep(5 * time.Second) | ||
sendSignal() | ||
}() | ||
handleSignal() | ||
} | ||
|
||
// 创建一个等待信号的进程 | ||
func simpleSignal() { | ||
sigRecv := make(chan os.Signal, 1) | ||
sigs := []os.Signal{syscall.SIGINT, syscall.SIGQUIT,syscall.SIGTERM} | ||
signal.Notify(sigRecv, sigs...) | ||
for sig := range sigRecv { | ||
fmt.Printf("Received a signal:%s\n", sig) | ||
} | ||
} | ||
|
||
func handleSignal() { | ||
sigRecv1 := make(chan os.Signal, 1) | ||
sigs1 := []os.Signal{syscall.SIGINT, syscall.SIGQUIT} | ||
fmt.Printf("Set notification for %s... [sigRecv1]\n", sigs1) | ||
signal.Notify(sigRecv1, sigs1...) | ||
sigRecv2 := make(chan os.Signal, 1) | ||
sigs2 := []os.Signal{syscall.SIGQUIT} | ||
fmt.Printf("Set notification for %s... [sigRecv2]\n", sigs2) | ||
signal.Notify(sigRecv2, sigs2...) | ||
|
||
var wg sync.WaitGroup | ||
wg.Add(2) | ||
go func() { | ||
for sig := range sigRecv1 { | ||
fmt.Printf("Received a signal from sigRecv1: %s\n", sig) | ||
} | ||
fmt.Printf("End. [sigRecv1]\n") | ||
wg.Done() | ||
}() | ||
go func() { | ||
for sig := range sigRecv2 { | ||
fmt.Printf("Received a signal from sigRecv2: %s\n", sig) | ||
} | ||
fmt.Printf("End. [sigRecv2]\n") | ||
wg.Done() | ||
}() | ||
|
||
fmt.Println("Wait for 2 seconds... ") | ||
time.Sleep(2 * time.Second) | ||
fmt.Printf("Stop notification...") | ||
signal.Stop(sigRecv1) // 取消之前调用 signal.Notify 函数时告知signal处理程序需要自行处理若干信号的行为, | ||
close(sigRecv1) // 只有把当初传递给signal.Notify函数的那个signal 接受通道作为调用signal.stop函数时的参数值,才能取消行为 | ||
fmt.Printf("done. [sigRecv1]\n") | ||
wg.Wait() | ||
} | ||
|
||
func sendSignal() { | ||
defer func() { | ||
if err := recover(); err != nil { | ||
fmt.Printf("Fatal Error: %s\n", err) | ||
debug.PrintStack() | ||
} | ||
}() | ||
// ps aux | grep "signal" | grep -v "grep" | grep -v "go run" | awk '{print $2}' | ||
cmds := []*exec.Cmd{ | ||
exec.Command("ps", "aux"), | ||
exec.Command("grep", "signal"), | ||
exec.Command("grep", "-v", "grep"), | ||
exec.Command("grep", "-v", "go run"), | ||
exec.Command("awk", "{print $2}"), | ||
} | ||
output, err := runCmds(cmds) | ||
if err != nil { | ||
fmt.Printf("Command Execution Error: %s\n", err) | ||
return | ||
} | ||
pids, err := getPids(output) | ||
if err != nil { | ||
fmt.Printf("PID Parsing Error: %s\n", err) | ||
return | ||
} | ||
fmt.Printf("Target PID(s):\n%v\n", pids) | ||
for _, pid := range pids { | ||
proc, err := os.FindProcess(pid) | ||
if err != nil { | ||
fmt.Printf("Process Finding Error: %s\n", err) | ||
return | ||
} | ||
sig := syscall.SIGQUIT | ||
fmt.Printf("Send signal '%s' to the process (pid=%d)...\n", sig, pid) | ||
err = proc.Signal(sig) | ||
if err != nil { | ||
fmt.Printf("Signal Sending Error: %s\n", err) | ||
return | ||
} | ||
} | ||
} | ||
|
||
func getPids(strs []string) ([]int, error) { | ||
var pids []int | ||
for _, str := range strs { | ||
pid, err := strconv.Atoi(strings.TrimSpace(str)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
pids = append(pids, pid) | ||
} | ||
return pids, nil | ||
} | ||
|
||
func runCmds(cmds []*exec.Cmd) ([]string, error) { | ||
if cmds == nil || len(cmds) == 0 { | ||
return nil, errors.New("The cmd slice is invalid!") | ||
} | ||
first := true | ||
var output []byte | ||
var err error | ||
for _, cmd := range cmds { | ||
fmt.Printf("Run command: %v\n", getCmdPlaintext(cmd)) | ||
if !first { | ||
var stdinBuf bytes.Buffer | ||
stdinBuf.Write(output) | ||
cmd.Stdin = &stdinBuf | ||
} | ||
var stdoutBuf bytes.Buffer | ||
cmd.Stdout = &stdoutBuf | ||
if err = cmd.Start(); err != nil { | ||
return nil, getError(err, cmd) | ||
} | ||
if err = cmd.Wait(); err != nil { | ||
return nil, getError(err, cmd) | ||
} | ||
output = stdoutBuf.Bytes() | ||
//fmt.Printf("Output:\n%s\n", string(output)) | ||
if first { | ||
first = false | ||
} | ||
} | ||
var lines []string | ||
var outputBuf bytes.Buffer | ||
outputBuf.Write(output) | ||
for { | ||
line, err := outputBuf.ReadBytes('\n') | ||
if err != nil { | ||
if err == io.EOF { | ||
break | ||
} else { | ||
return nil, getError(err, nil) | ||
} | ||
} | ||
lines = append(lines, string(line)) | ||
} | ||
return lines, nil | ||
} | ||
|
||
func getCmdPlaintext(cmd *exec.Cmd) string { | ||
var buf bytes.Buffer | ||
buf.WriteString(cmd.Path) | ||
for _, arg := range cmd.Args[1:] { | ||
buf.WriteRune(' ') | ||
buf.WriteString(arg) | ||
} | ||
return buf.String() | ||
} | ||
|
||
func getError(err error, cmd *exec.Cmd, extraInfo ...string) error { | ||
var errMsg string | ||
if cmd != nil { | ||
errMsg = fmt.Sprintf("%s [%s %v]", err, (*cmd).Path, (*cmd).Args) | ||
} else { | ||
errMsg = fmt.Sprintf("%s", err) | ||
} | ||
if len(extraInfo) > 0 { | ||
errMsg = fmt.Sprintf("%s (%v)", errMsg, extraInfo) | ||
} | ||
return errors.New(errMsg) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/** | ||
* Socket 来啦!!! | ||
* | ||
* @author ShaoWei Pu <marco0727@gamil.com> | ||
* @date 2017/10/10 | ||
* ------------------------------------------------------------- | ||
* 0x01. 深入理解TPC/IP [晚上回去一定要看要看要看要看看看...] | ||
* 0x02. | ||
*/ | ||
package main | ||
|
||
func main() { | ||
|
||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package Debug | ||
|
||
import ( | ||
"runtime" | ||
"fmt" | ||
) | ||
|
||
/** | ||
返回调用位置信息 | ||
*/ | ||
func ErrorMsg(entity error) { | ||
if pc, file, line, ok := runtime.Caller(1); ok != false { | ||
f := runtime.FuncForPC(pc) | ||
fmt.Printf(" [调用方法] %s \n [调用位置] %s %v \n [ErrorMsg] %s\n", f.Name(), file, line, entity) | ||
} | ||
return | ||
} |