mirror of
https://github.com/jbranchaud/til
synced 2026-01-20 15:38:02 +00:00
Compare commits
4 Commits
5809bf72f1
...
38ac88b5e2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38ac88b5e2 | ||
|
|
aeb55efc3c | ||
|
|
5615da920f | ||
|
|
c60c63f554 |
@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
|
|||||||
|
|
||||||
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
||||||
|
|
||||||
_1541 TILs and counting..._
|
_1542 TILs and counting..._
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ _1541 TILs and counting..._
|
|||||||
- [Aliasing An Ansible Host](devops/aliasing-an-ansible-host.md)
|
- [Aliasing An Ansible Host](devops/aliasing-an-ansible-host.md)
|
||||||
- [Allow Cross-Origin Requests To Include Cookies](devops/allow-cross-origin-requests-to-include-cookies.md)
|
- [Allow Cross-Origin Requests To Include Cookies](devops/allow-cross-origin-requests-to-include-cookies.md)
|
||||||
- [Allow HTTPS Through Your UFW Firewall](devops/allow-https-through-your-ufw-firewall.md)
|
- [Allow HTTPS Through Your UFW Firewall](devops/allow-https-through-your-ufw-firewall.md)
|
||||||
- [Check For Cached Site Assocation File For iOS](devops/check-for-cached-site-association-file-for-ios.md)
|
- [Check For Cached Site Association File For iOS](devops/check-for-cached-site-association-file-for-ios.md)
|
||||||
- [Check The Status of All Services](devops/check-the-status-of-all-services.md)
|
- [Check The Status of All Services](devops/check-the-status-of-all-services.md)
|
||||||
- [Check The Syntax Of nginx Files](devops/check-the-syntax-of-nginx-files.md)
|
- [Check The Syntax Of nginx Files](devops/check-the-syntax-of-nginx-files.md)
|
||||||
- [Connect To An RDS PostgreSQL Database](devops/connect-to-an-rds-postgresql-database.md)
|
- [Connect To An RDS PostgreSQL Database](devops/connect-to-an-rds-postgresql-database.md)
|
||||||
@@ -405,6 +405,7 @@ _1541 TILs and counting..._
|
|||||||
- [Build For A Specific OS And Architecture](go/build-for-a-specific-os-and-architecture.md)
|
- [Build For A Specific OS And Architecture](go/build-for-a-specific-os-and-architecture.md)
|
||||||
- [Check If Cobra Flag Was Set](go/check-if-cobra-flag-was-set.md)
|
- [Check If Cobra Flag Was Set](go/check-if-cobra-flag-was-set.md)
|
||||||
- [Combine Two Slices](go/combine-two-slices.md)
|
- [Combine Two Slices](go/combine-two-slices.md)
|
||||||
|
- [Detect If Stdin Comes From A Redirect](go/detect-if-stdin-comes-from-a-redirect.md)
|
||||||
- [Do Something N Times](go/do-something-n-times.md)
|
- [Do Something N Times](go/do-something-n-times.md)
|
||||||
- [Find Executables Installed By Go](go/find-executables-installed-by-go.md)
|
- [Find Executables Installed By Go](go/find-executables-installed-by-go.md)
|
||||||
- [Format Date And Time With Time Constants](go/format-date-and-time-with-time-constants.md)
|
- [Format Date And Time With Time Constants](go/format-date-and-time-with-time-constants.md)
|
||||||
@@ -744,7 +745,7 @@ _1541 TILs and counting..._
|
|||||||
- [Check If Clusters Are Upgrade Compatible](postgres/check-if-clusters-are-upgrade-compatible.md)
|
- [Check If Clusters Are Upgrade Compatible](postgres/check-if-clusters-are-upgrade-compatible.md)
|
||||||
- [Check If The Local Server Is Running](postgres/check-if-the-local-server-is-running.md)
|
- [Check If The Local Server Is Running](postgres/check-if-the-local-server-is-running.md)
|
||||||
- [Check If User Role Exists For Database](postgres/check-if-user-role-exists-for-database.md)
|
- [Check If User Role Exists For Database](postgres/check-if-user-role-exists-for-database.md)
|
||||||
- [Check Table For Any Oprhaned Records](postgres/check-table-for-any-orphaned-records.md)
|
- [Check Table For Any Orphaned Records](postgres/check-table-for-any-orphaned-records.md)
|
||||||
- [Checking Inequality](postgres/checking-inequality.md)
|
- [Checking Inequality](postgres/checking-inequality.md)
|
||||||
- [Checking The Type Of A Value](postgres/checking-the-type-of-a-value.md)
|
- [Checking The Type Of A Value](postgres/checking-the-type-of-a-value.md)
|
||||||
- [Clear The Screen In psql](postgres/clear-the-screen-in-psql.md)
|
- [Clear The Screen In psql](postgres/clear-the-screen-in-psql.md)
|
||||||
|
|||||||
59
go/detect-if-stdin-comes-from-a-redirect.md
Normal file
59
go/detect-if-stdin-comes-from-a-redirect.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Detect If Stdin Comes From A Redirect
|
||||||
|
|
||||||
|
Reading lines of input from `stdin` is flexible. And we may need our program to
|
||||||
|
behave differently depending on where that input is coming from. For instance,
|
||||||
|
if data is redirected or piped to our program, we scan and process it directly.
|
||||||
|
Otherwise, we need to prompt the user to enter in specific info and go from
|
||||||
|
there.
|
||||||
|
|
||||||
|
We can detect whether [`os.Stdin`](https://pkg.go.dev/os#pkg-variables) is
|
||||||
|
being piped to, redirected to, or whether we should prompt the user by looking
|
||||||
|
at the file mode descriptor of
|
||||||
|
[`os.Stdin.Stat()`](https://pkg.go.dev/os#File.Stat).
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
file, err := os.Stdin.Stat()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error checking stdin: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fromTerminal := (file.Mode() & os.ModeCharDevice) != 0
|
||||||
|
fromAPipe := (file.Mode() & os.ModeNamedPipe) != 0
|
||||||
|
|
||||||
|
if fromTerminal {
|
||||||
|
fmt.Println("This is Char Device mode, let's prompt user for input")
|
||||||
|
termScanner := bufio.NewScanner(os.Stdin)
|
||||||
|
for termScanner.Scan() {
|
||||||
|
fmt.Printf("- %s\n", termScanner.Text())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if fromAPipe {
|
||||||
|
fmt.Println("This is Named Pipe mode, contents piped in")
|
||||||
|
pipeScanner := bufio.NewScanner(os.Stdin)
|
||||||
|
for pipeScanner.Scan() {
|
||||||
|
fmt.Printf("- %s\n", pipeScanner.Text())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("This means the input was redirected")
|
||||||
|
redirectScanner := bufio.NewScanner(os.Stdin)
|
||||||
|
for redirectScanner.Scan() {
|
||||||
|
fmt.Printf("- %s\n", redirectScanner.Text())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If `os.ModeCharDevice` then we are connected to a character device, like the
|
||||||
|
terminal. We can see if input is being piped in by checking against
|
||||||
|
`os.ModeNamedPipe`. Otherwise, there are a variety of file modes and I'm
|
||||||
|
willing to assume we're dealing with a regular file redirect at that point.
|
||||||
Reference in New Issue
Block a user