Implementing SFTP File Management in WebShell
After enabling web-based terminal access via WebShell, users also need visual file management: upload/download, permission changes, inline editing, etc. Here’s a summary of the implementation.
ssh2 + ssh2-sftp-client
After solving the terminal connection with ssh2, use ssh2-sftp-client to perform file operations:
listto fetch file lists- Returns file type, name, owner uid, group gid, size, atime, mtime
- For symlinks,
typeisl; hard links appear as-
get/putfor streaming upload/downloadrenameto rename filesdeleteto delete filesstatto get file infomkdirto create directoriesrenameto rename files
These cover the basics, but there are additional concerns.
Issues
- Check whether the current user has permissions
First determine the current user’s uid/gid. Use ssh2.exec to run id to obtain them. Then compare with the file’s uid/gid from list/stat to infer permissions.
- User list
The GUI needs to change file ownership. Since list/stat provides uid/gid, you only need a user list. For example:
# Output format:
# root,0
grep /bin/bash /etc/passwd | awk -F: '{print $1 "," $3}'
Hidden files in lists
To hide dotfiles, pass a filter (regex in older versions) when listing:
conn.list(path, /^[^.]/);Note: SFTP doesn’t support server-side filtering;
ssh2still fetches all entries and filters client-side. In ssh2-sftp-client v9,listswitched from regex to a callback filter, which still works for this.Use the terminal session’s current working directory as the default open path
Strictly speaking this is terminal-side, not SFTP. But it greatly improves UX. Implement via terminal hooks: after each command, run
pwdand send the result to the client. The client parses and caches the path; when opening SFTP, pass it as the initialpath.source /usr/local/bash-precmd/bash-preexec.sh preexec() { printf "\x1B]1337;PreExec;Timestamp=$(date +%s);\x7"; } precmd() { printf "\x1B]1337;PostExec;Exit=$?;CurrentDir=$(pwd);Timestamp=$(date +%s);CurrentUser=$USER;\x7"; }
Beyond SFTP, there are other cases such as kubectl.
kubectl
If managing containers via kubectl, SFTP won’t work. You’ll need to execute commands and parse the results.
Use
lsand friends to list files. Note that commands differ across container OSes and may need branching.ls -l --time-style=full-iso /- Add
-Ato hide dotfiles --time-style=full-isostabilizes time format regardless of system locale
- Add
Avoid
statfor file properties since output can be localized (e.g., “directory” differs by locale). Preferlswith-dso the result is a single entry for the target file/dir. Also note that unlikels -l, there’s no first-line summary.ls -ld --time-style=full-iso /
Final Thoughts
- The above outlines the main path; real-world implementations are more complex, but the key points are here.
- After WebShell shipped file management, long-term observations showed it became the No.1 used feature—clearly very important.

