-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshell.go
More file actions
134 lines (98 loc) · 3.71 KB
/
Copy pathshell.go
File metadata and controls
134 lines (98 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package main
import (
"fmt"
"io/ioutil"
"os"
ps "github.com/mitchellh/go-ps"
)
func showHelp() {
fmt.Println(`Usage: lup [OPTION] COMMANDLINE
Run multiple similar commands expanding at-symbol encapsulated, comma-separated lists similarly to nested for loops.
e.g:
lup @rm,nano@ foo_@1,2@
Expands to and executes:
rm foo_1
rm foo_2
nano foo_1
nano foo_2
If @ symbols in a command or commas (within an @ group) are to be used as literals they should be escaped with backslashes, as should commas which are to be treated as literals within @ groups. When not enclosed in quotes, @s should be escaped with double-backslashes.
Iterating
---------
To iterate through a range of numbers, use @i..j@ where i and j are integer values. Lup will increment or decrement as required, for example.
lup echo "@9..0@@0..9@"
Hiding
------
To "hide" a group, you can prefix its contents with -: the following will echo iterate through the hidden block echoing "Hello" 5 times, but otherwise do nothing with its values
lup @-:1..5@ echo "Hello"
Backrefs
--------
You can reference previous blocks in a command by including a standalone integer reference to it in an @ block. We can rework the previous example to echo the contents of the hidden block after the word "Hello" (note: backref values begin at 1 and are a copy of the specific value used in that group on any given line, they are not iterated through as independent loops)
lup @-:1..5@ echo "Hello @1@"
Reading Files
-------------
Text files can be used in @ blocks and injected line by line. For example, given a file containing a list of servers:
Fry
Leela
Bender
We can perform an action on each line by using @lines:...@
$ lup -t echo @lines:/tmp/foo/servers.txt@
echo Fry
echo Leela
echo Bender
Filesystem
----------
Directives are available for iterating through files/directories/everything in a specific path. These are 'files,' 'dirs,' and 'all' respectively.
When provided with a relative path, the relative path and file/dir names will be used, e.g.:
$ lup echo @files:foo/*@
foo/bar.txt
foo/baz.sh
When provided with an absolute path (whether explicit or expanded), only the file/directory name will be used:
$ lup echo @files:$(pwd)/foo/*@
bar.txt
baz.sh
When a path is provided immediately before an @ group containing a files/dirs/all directive, the path is inherited:
$ lup echo $(pwd)/foo/@files:*@
/tmp/foo/bar.txt
/tmp/foo/baz.sh
It is important to note that only the filename is being returned again - the full paths are shown because the rest of the path exists outside the @ group, we can prove this with a backref.
$ lup echo "$(pwd)/foo/@files:*@ (@1@)"
/tmp/foo/bar.txt (bar.txt)
/tmp/foo/baz.sh (baz.sh)
If, however, a path is provided immediately prior to an @ group containing a files/dirs/all directive which contains a wildcard, the *entire path* will be returned.
$ lup echo "$(pwd)/f*o/@files:*@ (@1@)"
/tmp/foo/bar.txt (/tmp/foo/bar.txt)
/tmp/foo/baz.sh (/tmp/foo/baz.sh)
More detail on usage is available at https://github.com/udkyo/lup
Options:
-h, --help Show this help message and exit
-V, --version Show version information and exit
-t, --test Show commands, but do not execute them`)
if !testrun {
os.Exit(0)
}
}
func detectShell() string {
p, err := ps.FindProcess(os.Getppid())
if err != nil {
errOn(err, "Couldn't detect shell", 14)
}
return (p.Executable())
}
func getStdin() string {
inp := ""
file := os.Stdin
fi, err := file.Stat()
if err != nil {
fmt.Fprintln(os.Stderr, "file.Stat()", err)
os.Exit(3)
}
size := fi.Size()
if size > 0 {
data, _ := ioutil.ReadAll(os.Stdin)
inp = string(data)
if len(inp) > 0 {
inp = inp[:len(string(data))-1]
}
}
return inp
}