@@ -6,6 +6,7 @@ use pop_launcher::*;
6
6
7
7
use flume:: Sender ;
8
8
use futures:: StreamExt ;
9
+ use regex:: Regex ;
9
10
use std:: collections:: VecDeque ;
10
11
use std:: path:: { Path , PathBuf } ;
11
12
use std:: process:: Stdio ;
@@ -54,11 +55,42 @@ impl App {
54
55
55
56
async fn activate ( & mut self , id : u32 ) {
56
57
if let Some ( script) = self . scripts . get ( id as usize ) {
57
- let interpreter = script. interpreter . as_deref ( ) . unwrap_or ( "sh" ) ;
58
+ let mut shell: String = Default :: default ( ) ;
59
+ let mut args: Vec < & OsStr > = Vec :: new ( ) ;
60
+
61
+ let program = script
62
+ . interpreter
63
+ . as_deref ( )
64
+ . and_then ( |interpreter| {
65
+ // split the shebang into parts, e.g. ["/bin/bash"], or a more complex ["/usr/bin/env", "bash"]
66
+ let mut parts = interpreter. split_ascii_whitespace ( ) ;
67
+
68
+ // first part must be the command to run, e.g. "/usr/bin/env"
69
+ let command = parts. next ( ) ?;
70
+
71
+ for arg in parts {
72
+ args. push ( arg. as_ref ( ) ) ;
73
+ }
74
+
75
+ Some ( command)
76
+ } )
77
+ . or_else ( || {
78
+ if let Ok ( string) = std:: env:: var ( "SHELL" ) {
79
+ shell = string;
80
+ return Some ( & shell) ;
81
+ }
82
+
83
+ None
84
+ } )
85
+ . unwrap_or ( "sh" ) ;
86
+
87
+ // add the script file itself as a final arg for the interpreter
88
+ args. push ( script. path . as_ref ( ) ) ;
89
+
58
90
send ( & mut self . out , PluginResponse :: Close ) . await ;
59
91
60
- let _ = Command :: new ( interpreter )
61
- . arg ( script . path . as_os_str ( ) )
92
+ let _ = Command :: new ( program )
93
+ . args ( args )
62
94
. stdin ( Stdio :: null ( ) )
63
95
. stdout ( Stdio :: null ( ) )
64
96
. stderr ( Stdio :: null ( ) )
@@ -156,6 +188,8 @@ async fn load_from(path: &Path, paths: &mut VecDeque<PathBuf>, tx: Sender<Script
156
188
}
157
189
158
190
tokio:: spawn ( async move {
191
+ let shebang_re = Regex :: new ( r"^!\s*" ) . unwrap ( ) ;
192
+
159
193
let mut file = match tokio:: fs:: File :: open ( & path) . await {
160
194
Ok ( file) => tokio:: io:: BufReader :: new ( file) . lines ( ) ,
161
195
Err ( why) => {
@@ -180,8 +214,8 @@ async fn load_from(path: &Path, paths: &mut VecDeque<PathBuf>, tx: Sender<Script
180
214
181
215
if first {
182
216
first = false ;
183
- if let Some ( interpreter ) = line . strip_prefix ( '!' ) {
184
- info. interpreter = Some ( interpreter . to_owned ( ) ) ;
217
+ if shebang_re . is_match ( line ) {
218
+ info. interpreter = Some ( shebang_re . replace ( line , "" ) . to_string ( ) ) ;
185
219
continue ;
186
220
}
187
221
}
0 commit comments