Skip to content

Commit a0c33db

Browse files
yamyayhengyunabc
authored andcommitted
Add tee command for pipes (alibaba#976)
1 parent 778ffa2 commit a0c33db

File tree

6 files changed

+183
-1
lines changed

6 files changed

+183
-1
lines changed

core/src/main/java/com/taobao/arthas/core/command/BuiltinCommandPack.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.taobao.arthas.core.command.basic1000.StopCommand;
1414
import com.taobao.arthas.core.command.basic1000.SystemEnvCommand;
1515
import com.taobao.arthas.core.command.basic1000.SystemPropertyCommand;
16+
import com.taobao.arthas.core.command.basic1000.TeeCommand;
1617
import com.taobao.arthas.core.command.basic1000.VMOptionCommand;
1718
import com.taobao.arthas.core.command.basic1000.VersionCommand;
1819
import com.taobao.arthas.core.command.hidden.JulyCommand;
@@ -102,6 +103,7 @@ private static void initCommands() {
102103
commands.add(Command.create(PwdCommand.class));
103104
commands.add(Command.create(MBeanCommand.class));
104105
commands.add(Command.create(GrepCommand.class));
106+
commands.add(Command.create(TeeCommand.class));
105107
commands.add(Command.create(ProfilerCommand.class));
106108
}
107109
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.taobao.arthas.core.command.basic1000;
2+
3+
4+
import com.taobao.arthas.core.command.Constants;
5+
import com.taobao.arthas.core.shell.command.AnnotatedCommand;
6+
import com.taobao.arthas.core.shell.command.CommandProcess;
7+
import com.taobao.middleware.cli.annotations.*;
8+
9+
/**
10+
* @author min.yang
11+
*/
12+
@Name("tee")
13+
@Summary("tee command for pipes." )
14+
@Description(Constants.EXAMPLE +
15+
" sysprop | tee /path/to/logfile | grep java \n" +
16+
" sysprop | tee -a /path/to/logfile | grep java \n"
17+
+ Constants.WIKI + Constants.WIKI_HOME + "tee")
18+
public class TeeCommand extends AnnotatedCommand {
19+
20+
private String filePath;
21+
private boolean append;
22+
23+
@Argument(index = 0, argName = "file", required = false)
24+
@Description("File path")
25+
public void setFilePath(String filePath) {
26+
this.filePath = filePath;
27+
}
28+
29+
@Option(shortName = "a", longName = "append", flag = true)
30+
@Description("Append to file")
31+
public void setRegEx(boolean append) {
32+
this.append = append;
33+
}
34+
35+
@Override
36+
public void process(CommandProcess process) {
37+
process.write("The tee command only for pipes. See 'tee --help'\n");
38+
process.end();
39+
}
40+
41+
public String getFilePath() {
42+
return filePath;
43+
}
44+
45+
public boolean isAppend() {
46+
return append;
47+
}
48+
}

core/src/main/java/com/taobao/arthas/core/shell/command/internal/StdoutHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ public static StdoutHandler inject(List<CliToken> tokens) {
3030
return PlainTextHandler.inject(tokens);
3131
} else if (firstTextToken.value().equals(WordCountHandler.NAME)) {
3232
return WordCountHandler.inject(tokens);
33-
} else {
33+
} else if (firstTextToken.value().equals(TeeHandler.NAME)){
34+
return TeeHandler.inject(tokens);
35+
} else{
3436
return null;
3537
}
3638
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.taobao.arthas.core.shell.command.internal;
2+
3+
import com.taobao.arthas.core.command.basic1000.TeeCommand;
4+
import com.taobao.arthas.core.shell.cli.CliToken;
5+
import com.taobao.arthas.core.util.StringUtils;
6+
import com.taobao.middleware.cli.CLI;
7+
import com.taobao.middleware.cli.CommandLine;
8+
import com.taobao.middleware.cli.annotations.CLIConfigurator;
9+
10+
import java.io.*;
11+
import java.util.List;
12+
13+
/**
14+
* @author min.yang
15+
*/
16+
public class TeeHandler extends StdoutHandler implements CloseFunction {
17+
public static final String NAME = "tee";
18+
private PrintWriter out;
19+
private static CLI cli = null;
20+
21+
public TeeHandler(String filePath, boolean append) throws IOException {
22+
if (StringUtils.isEmpty(filePath)) {
23+
return;
24+
}
25+
File file = new File(filePath);
26+
27+
if (file.isDirectory()) {
28+
throw new IOException(filePath + ": Is a directory");
29+
}
30+
31+
if (!file.exists()) {
32+
File parentFile = file.getParentFile();
33+
if (parentFile != null) {
34+
parentFile.mkdirs();
35+
}
36+
}
37+
out = new PrintWriter(new BufferedWriter(new FileWriter(file, append)));
38+
}
39+
40+
public static StdoutHandler inject(List<CliToken> tokens) {
41+
List<String> args = StdoutHandler.parseArgs(tokens, NAME);
42+
43+
TeeCommand teeCommand = new TeeCommand();
44+
if (cli == null) {
45+
cli = CLIConfigurator.define(TeeCommand.class);
46+
}
47+
CommandLine commandLine = cli.parse(args, true);
48+
49+
try {
50+
CLIConfigurator.inject(commandLine, teeCommand);
51+
} catch (Throwable e) {
52+
throw new RuntimeException(e);
53+
}
54+
55+
String filePath = teeCommand.getFilePath();
56+
boolean append = teeCommand.isAppend();
57+
try {
58+
return new TeeHandler(filePath, append);
59+
} catch (IOException e) {
60+
throw new RuntimeException(e);
61+
}
62+
}
63+
64+
@Override
65+
public String apply(String data) {
66+
data = super.apply(data);
67+
if (out != null) {
68+
out.write(data);
69+
out.flush();
70+
}
71+
return data;
72+
}
73+
74+
@Override
75+
public void close() {
76+
if (out != null) {
77+
out.close();
78+
}
79+
}
80+
}

site/src/site/sphinx/en/tee.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
tee
2+
===
3+
4+
> Similar to the traditional `tee` command.
5+
6+
7+
```
8+
USAGE:
9+
tee [-a] [-h] [file]
10+
11+
SUMMARY:
12+
tee command for pipes.
13+
14+
EXAMPLES:
15+
sysprop | tee /path/to/logfile | grep java
16+
sysprop | tee -a /path/to/logfile | grep java
17+
18+
WIKI:
19+
https://alibaba.github.io/arthas/tee
20+
21+
OPTIONS:
22+
-a, --append Append to file
23+
-h, --help this help
24+
<file> File path
25+
```

site/src/site/sphinx/tee.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
tee
2+
===
3+
4+
> 类似传统的`tee`命令。
5+
6+
7+
```
8+
USAGE:
9+
tee [-a] [-h] [file]
10+
11+
SUMMARY:
12+
tee command for pipes.
13+
14+
EXAMPLES:
15+
sysprop | tee /path/to/logfile | grep java
16+
sysprop | tee -a /path/to/logfile | grep java
17+
18+
WIKI:
19+
https://alibaba.github.io/arthas/tee
20+
21+
OPTIONS:
22+
-a, --append Append to file
23+
-h, --help this help
24+
<file> File path
25+
```

0 commit comments

Comments
 (0)